/**
 @file sys_tsingma_datapath.c

 @date 2023-02-09

 @version v0.1

*/

/****************************************************************
 *
 * Header Files
 *
 ***************************************************************/
#include "ctc_error.h"
#include "ctc_port.h"
#include "sys_usw_chip.h"
#include "sys_usw_datapath.h"
#include "sys_usw_qos_api.h"
#include "sys_usw_mac.h"
#include "sys_usw_peri.h"
#include "sys_usw_dmps.h"
#include "sys_usw_dmps_db.h"
#include "sys_usw_wb_common.h"
#include "sys_usw_mcu.h"
#include "sys_usw_dmps_drv_def.h"
#include "sys_tmg_datapath.h"
#include "sys_tmg_mac.h"
#include "sys_tmg_serdes.h"
#include "drv_api.h"
#include "usw/include/drv_chip_ctrl.h"
#include "usw/include/drv_common.h"
#include "sys_usw_register.h"


/****************************************************************************
 *
* Global and Declaration
*
*****************************************************************************/
extern sal_file_t g_tm_dump_fp;
extern const uint8 g_dmps_dbg_sw;
extern uint8 g_print_tbl;
extern uint32 g_port_link_mode;


#ifdef DRV_IOW_FIELD
#undef DRV_IOW_FIELD
#define DRV_IOW_FIELD(lchip, memid, fieldid, value, ptr) \
     do\
     {\
         int retv = 0;\
         char   fld_str[64] = {0};\
         retv = drv_set_field(lchip, memid, fieldid, ptr, value);\
         if (retv < 0)\
         {\
             return(retv); \
         }\
         drv_usw_get_field_string_by_id(lchip, memid, fieldid, fld_str);\
         if ((NULL != g_tm_dump_fp) && (g_dmps_dbg_sw)) \
         {\
             sal_fprintf(g_tm_dump_fp, "write %s 0 %s 0x%x\n", \
                 TABLE_NAME(lchip, memid), fld_str, *value); \
             sal_fflush(g_tm_dump_fp);\
         }\
     }\
     while(0)
                                         
#endif

/* DRV_IOW_FIELD extender, for index Not Zero */
#define DRV_IOW_FIELD_NZ(lchip, memid, fieldid, value, ptr, inst, index) \
     do\
     {\
         int retv = 0;\
         char   fld_str[64] = {0};\
         retv = drv_set_field(lchip, memid, fieldid, ptr, value);\
         if (retv < 0)\
         {\
             return(retv); \
         }\
         drv_usw_get_field_string_by_id(lchip, memid, fieldid, fld_str);\
         if ((NULL != g_tm_dump_fp) && (g_dmps_dbg_sw)) \
         {\
             sal_fprintf(g_tm_dump_fp, "//write chip 0 tbl-reg  %s.%d  %d  field %s %d\n", \
                 TABLE_NAME(lchip, memid), inst, index, fld_str, *value); \
             sal_fflush(g_tm_dump_fp);\
         }\
     }\
     while(0)

#define DP_DEBUG_FUNCTION_CALLED_PRINT() \
                    do \
                    { \
                        if ((NULL != g_tm_dump_fp) && (g_dmps_dbg_sw)) \
                        {\
                            sal_fprintf(g_tm_dump_fp, "//------ %s enter ----------------\n", __func__); \
                        }\
                    } \
                    while(0)
                
#define DP_DEBUG_FUNCTION_RETURN_PRINT() \
                    do \
                    { \
                        if ((NULL != g_tm_dump_fp) && (g_dmps_dbg_sw)) \
                        {\
                            sal_fprintf(g_tm_dump_fp, "//------ %s return ----------------\n", __func__); \
                        }\
                    } \
                    while(0)

#define DMPS_DUMP_PRINT(...)  do { \
        if(g_dmps_dbg_sw && g_tm_dump_fp) {\
            sal_fprintf(g_tm_dump_fp, __VA_ARGS__);\
            sal_fflush(g_tm_dump_fp); }\
    } while(0)


                                 /*CPUMAC0 CPUMAC1 LOO0 LOO1 LOO2 LOO3 OAM  DMATX0 DMATX1*/
uint16 g_tmg_misc_wrr_weight[9] = {100,    50,     200, 25,  200, 25,  100, 50,    50};

const sys_tmg_dmps_id_dictionary_s g_dmps_map_tmg[SYS_TMG_MAX_SERDES_NUM] = {
    {0,     0,     0,       0,         },            /*0*/
    {0,     0,     0,       1,         },            /*1*/
    {0,     0,     0,       2,         },            /*2*/
    {0,     0,     0,       3,         },            /*3*/
    {0,     0,     0,       4,         },            /*4*/
    {0,     0,     0,       5,         },            /*5*/
    {0,     0,     0,       6,         },            /*6*/
    {0,     0,     0,       7,         },            /*7*/
    {0,     0,     1,       16,        },            /*8*/
    {0,     0,     1,       17,        },            /*9*/
    {0,     0,     1,       18,        },            /*10*/
    {0,     0,     1,       19,        },            /*11*/
    {0,     0,     1,       20,        },            /*12*/
    {0,     0,     1,       21,        },            /*13*/
    {0,     0,     1,       22,        },            /*14*/
    {0,     0,     1,       23,        },            /*15*/
    {0,     0,     2,       32,        },            /*16*/
    {0,     0,     2,       33,        },            /*17*/
    {0,     0,     2,       34,        },            /*18*/
    {0,     0,     2,       35,        },            /*19*/
    {0,     0,     2,       36,        },            /*20*/
    {0,     0,     2,       37,        },            /*21*/
    {0,     0,     2,       38,        },            /*22*/
    {0,     0,     2,       39,        },            /*23*/
    {0,     0,     3,       48,        },            /*24*/
    {0,     0,     3,       49,        },            /*25*/
    {0,     0,     3,       50,        },            /*26*/
    {0,     0,     3,       51,        },            /*27*/
    {0,     0,     3,       52,        },            /*28*/
    {0,     0,     3,       53,        },            /*29*/
    {0,     0,     3,       54,        },            /*30*/
    {0,     0,     3,       55,        },            /*31*/
    {0,     0,     4,       64,        },            /*32*/
    {0,     0,     4,       65,        },            /*33*/
    {0,     0,     4,       66,        },            /*34*/
    {0,     0,     4,       67,        },            /*35*/
    {0,     0,     4,       68,        },            /*36*/
    {0,     0,     4,       69,        },            /*37*/
    {0,     0,     4,       70,        },            /*38*/
    {0,     0,     4,       71,        },            /*39*/
    {0,     1,     5,       0,         },            /*40*/
    {0,     1,     5,       1,         },            /*41*/
    {0,     1,     5,       2,         },            /*42*/
    {0,     1,     5,       3,         },            /*43*/
    {0,     1,     5,       4,         },            /*44*/
    {0,     1,     5,       5,         },            /*45*/
    {0,     1,     5,       6,         },            /*46*/
    {0,     1,     5,       7,         },            /*47*/
    {0,     1,     6,       16,        },            /*48*/
    {0,     1,     6,       17,        },            /*49*/
    {0,     1,     6,       18,        },            /*50*/
    {0,     1,     6,       19,        },            /*51*/
    {0,     1,     6,       20,        },            /*52*/
    {0,     1,     6,       21,        },            /*53*/
    {0,     1,     6,       22,        },            /*54*/
    {0,     1,     6,       23,        },            /*55*/
    {0,     1,     7,       32,        },            /*56*/
    {0,     1,     7,       33,        },            /*57*/
    {0,     1,     7,       34,        },            /*58*/
    {0,     1,     7,       35,        },            /*59*/
    {0,     1,     7,       36,        },            /*60*/
    {0,     1,     7,       37,        },            /*61*/
    {0,     1,     7,       38,        },            /*62*/
    {0,     1,     7,       39,        },            /*63*/
    {0,     1,     8,       48,        },            /*64*/
    {0,     1,     8,       49,        },            /*65*/
    {0,     1,     8,       50,        },            /*66*/
    {0,     1,     8,       51,        },            /*67*/
    {0,     1,     8,       52,        },            /*68*/
    {0,     1,     8,       53,        },            /*69*/
    {0,     1,     8,       54,        },            /*70*/
    {0,     1,     8,       55,        },            /*71*/
    {0,     1,     9,       64,        },            /*72*/
    {0,     1,     9,       65,        },            /*73*/
    {0,     1,     9,       66,        },            /*74*/
    {0,     1,     9,       67,        },            /*75*/
    {0,     1,     9,       68,        },            /*76*/
    {0,     1,     9,       69,        },            /*77*/
    {0,     1,     9,       70,        },            /*78*/
    {0,     1,     9,       71,        },            /*79*/
    {0,     0,     10,      80,        },            /*80*/
    {0,     0,     10,      81,        },            /*81*/
    {0,     1,     10,      80,        },            /*82*/
    {0,     1,     10,      81,        },            /*83*/
};

extern int32 _sys_tmg_mac_set_mac_config(uint8 lchip, uint16 mac_id);



extern int32
sys_tmg_mcu_init(uint8 lchip);
extern int32
sys_usw_dmps_db_dump(uint8 lchip, sal_file_t fp, ctc_global_dump_db_t* p_dump_param);
extern int32
sys_tmg_serdes_init(uint8 lchip);
extern int32 
_sys_tmg_serdes_speed_switch_proc(uint8 lchip, uint16 serdes_id, uint8 serdes_speed);
extern int32
sys_tmg_mcu_del_port_mapping(uint8 lchip, uint16 dport);
extern int32
sys_tmg_mcu_add_port_mapping(uint8 lchip, uint16 dport);
extern int32 
_sys_tmg_mac_cl73_reg_acc_init(uint8 lchip, uint16 serdes_id, uint32 en);

int32
_sys_tmg_datapath_set_map_by_chan(uint8 lchip, uint8 dp, uint16 dp_chan, uint8 dir);
int32 
_sys_tmg_datapath_set_general_calendar(uint8 lchip, uint8 dp_id);
int32
_sys_tmg_datapath_set_nettx_calendar(uint8 lchip, uint8 dp_id, uint32 dp_txqm_id);
STATIC int32
_sys_tmg_datapath_set_bufretrv_wrr_weight(uint8 lchip, uint8 dp);
int32
_sys_tmg_datapath_set_dp_netrx_cfg(uint8 lchip, uint8 dp);
uint32
_sys_tmg_datapath_get_dp_bw(uint8 lchip, uint8 dir, uint8 dp);
int32
_sys_tmg_datapath_set_nettx_timer(uint8 lchip, uint8 dp, uint16 dp_mac_client, uint8 dp_txqm, 
                                             uint16 speed, uint32 total_bw);
int32
_sys_tmg_datapath_set_nettx_credit(uint8 lchip, uint8 dp, uint16 dp_mac_id, uint16 speed);
int32
_sys_tmg_datapath_set_bufretrv_credit(uint8 lchip, uint8 dp, uint16 dp_chan, uint8 speed_mode);
int32
_sys_tmg_datapath_set_epe_credit(uint8 lchip, uint8 dp, uint16 mac_client, uint8 speed_mode);
int32
_sys_tmg_datapath_set_qmgr_credit(uint8 lchip, uint16 chan_id, uint8 speed_mode);
int32
_sys_tmg_datapath_epe_info_collect(uint8 lchip, uint8 dp, uint8 dp_txqm, 
                                              uint16* p_xg_bmp, uint16* p_lg_bmp, 
                                              uint16* p_wl_sum, uint16* p_wh_sum, 
                                              uint16 wp[SYS_TMG_MAC_CLIENT_NUM_PER_TXQM]);
int32
_sys_tmg_datapath_epe_port_enable(uint8 lchip, uint8 dp, uint32 dp_txqm, uint32 bmp);
int32
_sys_tmg_datapath_epe_nw_weight_cfg(uint8 lchip, uint8 dp, uint8 dp_txqm, uint16 net_weights[SYS_TMG_MAC_CLIENT_NUM_PER_TXQM]);
int32
_sys_tmg_datapath_epe_wrr_weight_cfg(uint8 lchip, uint8 dp, uint16 wl_sum[SYS_TMG_TXQM_NUM_PER_DP],
                                             uint16 wh_sum[SYS_TMG_TXQM_NUM_PER_DP]);
int32
_sys_tmg_datapath_qmgr_wrr_cfg(uint8 lchip);
int32
_sys_tmg_datapath_bufretrv_get_credit(uint8 lchip, uint16 speed, sys_datapath_bufsz_step_t *step);
uint32
_sys_tmg_datapath_epe_speed_to_credit(uint16 speed);
uint8
_sys_tmg_datapath_speedmode_to_qmgrcrdt(uint16 speed);
int32
_sys_tmg_datapath_calculate_general_calendar_parser(uint8 lchip, uint8 dp_id, uint16* cal, 
                                                    uint16* walk_end, sys_cal_info_collect_t* cal_info);
int32
_sys_tmg_datapath_nettx_common_calendar(uint8 lchip, uint8 dp_id, uint8 dp_txqm_id, uint8 *p_error, 
                                                     uint16 *p_walk_end, uint16 *p_cal, sys_cal_info_collect_t* cal_info);

/****************************************************************************
 *
* Function
*
*****************************************************************************/
uint8
_sys_tmg_datapath_is_dp_in_use(uint8 lchip, uint8 dp_id)
{
    uint32 mac_valid_bmp = 0;
    (void)sys_usw_dmps_db_get_mac_group_valid(lchip, 0, &mac_valid_bmp);
    /*bit 0~9:   HSS 0~9 valid flag       */
    /*bit 10:    CPUMAC in DP 0 valid flag*/
    /*bit 11~20: HSS 10~19 valid flag     */
    /*bit 21:    CPUMAC in DP 1 valid flag*/
    if(0 == ((mac_valid_bmp >> (dp_id * (SYS_TMG_MAX_HSS_NUM_PER_DP+1))) & 0x07ff))
    {
        return FALSE;
    }
    else
    {
        return TRUE;
    }
}

uint8
_sys_tmg_datapath_is_txqm_in_use(uint8 lchip, uint8 txqm_id)
{
    uint32 mac_valid_bmp = 0;
    (void)sys_usw_dmps_db_get_mac_group_valid(lchip, 0, &mac_valid_bmp);
    /*bit 0~9:   HSS 0~9 valid flag       */
    /*bit 10:    CPUMAC in DP 0 valid flag*/
    /*bit 11~20: HSS 10~19 valid flag     */
    /*bit 21:    CPUMAC in DP 1 valid flag*/
    if(SYS_TMG_TXQM_NUM_PER_DP > txqm_id)
    {
        if(0 == ((mac_valid_bmp >> (SYS_TMG_HSS_NUM_PER_TXQM * txqm_id)) & 0x3))
        {
            return FALSE;
        }
        else
        {
            return TRUE;
        }
    }
    else if(SYS_TMG_CPUMAC_TXQM_ID == txqm_id)
    {
        if(0 == (mac_valid_bmp & 0x00200400))
        {
            return FALSE;
        }
        else
        {
            return TRUE;
        }
    }
    else
    {
        if(0 == ((mac_valid_bmp >> (SYS_TMG_HSS_NUM_PER_TXQM * txqm_id + 1)) & 0x3))
        {
            return FALSE;
        }
        else
        {
            return TRUE;
        }
    }
}

uint8
_sys_tmg_datapath_is_hss_in_use(uint8 lchip, uint8 hss_id)
{
    uint32 mac_valid_bmp = 0;
    (void)sys_usw_dmps_db_get_mac_group_valid(lchip, 0, &mac_valid_bmp);
    /*bit 0~9:   HSS 0~9 valid flag       */
    /*bit 10:    CPUMAC in DP 0 valid flag*/
    /*bit 11~20: HSS 10~19 valid flag     */
    /*bit 21:    CPUMAC in DP 1 valid flag*/
    if(SYS_TMG_MAX_HSS_NUM_PER_DP > hss_id)
    {
        if(0 == ((mac_valid_bmp >> hss_id) & 0x1))
        {
            return FALSE;
        }
        else
        {
            return TRUE;
        }
    }
    else if(SYS_TMG_CPUMAC_HSS_ID == hss_id)
    {
        if(0 == (mac_valid_bmp & 0x00200400))
        {
            return FALSE;
        }
        else
        {
            return TRUE;
        }
    }
    else
    {
        if(0 == ((mac_valid_bmp >> (hss_id + 1)) & 0x1))
        {
            return FALSE;
        }
        else
        {
            return TRUE;
        }
    }
}

/*collecting mac id related speed and creating a temp database cal_info[] for calendar calculation*/
int32
_sys_tmg_calendar_speed_info_collect(uint8 lchip, sys_cal_info_collect_t cal_info[], 
                                                 uint8 dp_id, uint8 dp_txqm_id, uint8 cal_type)
{
    uint32 speed              = 0;
    uint16 mac_id             = 0;
    uint16 chan_id            = 0;
    uint16 dp_chan            = 0;
    uint16 mac_client         = 0;
    uint16 dp_mac_client      = 0;
    uint8  dp                 = 0;
    uint8  ocs                = 0;
    uint8  if_mode            = 0;
    uint8  speed_mode         = 0;
    uint8  p_chan_num         = 0;
    uint16 dport              = 0;
    uint8  port_type          = 0;
    /*uint8  if_type            = 0;*/
    uint8  dir                = 0;
    uint16 core_pll           = 0;
    /*uint8  care_ovclk         = FALSE;*/
    uint8  is_cpumac_cal      = FALSE;
    uint8  is_mac_fix         = FALSE;
    uint8  xpipe_dual         = 0;    /*0-skip xpipe chan  1-add xpipe chan  2-skip xpipe mode=6 chan*/
    uint16 p_chan_id[DMPS_MAX_NUM_PER_MODULE] = {0};
    sys_dmps_db_upt_info_t port_info          = {0};

    sal_memset(cal_info, 0, sizeof(sys_cal_info_collect_t) * SYS_TMG_MAC_CLIENT_NUM_PER_DP);

    /*judge calendar type to get proper options, which determine how to collect speed info*/
    switch(cal_type)
    {
        case SYS_DMPS_NETRX_CAL:
            is_cpumac_cal = FALSE;
            /*care_ovclk    = FALSE;*/
            is_mac_fix    = FALSE;
            xpipe_dual    = 1;
            dir           = CHAN_DIR_RX;
            break;
        case SYS_DMPS_EPE_CAL:
        case SYS_DMPS_BR_CAL:
            is_cpumac_cal = TRUE;
            /*care_ovclk    = FALSE;*/
            is_mac_fix    = FALSE;
            xpipe_dual    = 2;
            dir           = CHAN_DIR_TX;
            break;
        case SYS_DMPS_NETTX_CAL:
            is_cpumac_cal = FALSE;
            /*care_ovclk    = FALSE;*/
            is_mac_fix    = FALSE;
            xpipe_dual    = 0;
            dir           = CHAN_DIR_TX;
            break;
        default:
            return CTC_E_INVALID_PARAM;
    }

    /*network port collect*/
    for(dp_chan = 0; dp_chan < SYS_TMG_NW_CHAN_NUM_PER_DP; dp_chan++)
    {
        chan_id = SYS_TMG_CHANNEL_NUM_PER_DP*dp_id + dp_chan;
        SYS_CONDITION_CONTINUE(FALSE == sys_usw_dmps_db_is_valid_id(lchip, GET_CHAN_TYPE_BY_DIR(dir), chan_id));

        CTC_ERROR_RETURN(sys_usw_dmps_db_upt_info_init(lchip, &port_info));
        DMPS_DB_SET_MAP_INFO(port_info, GET_CHAN_ID_BY_DIR(dir), chan_id);
        DMPS_DB_SET_PROPERTY_UPDATE(port_info, DMPS_DB_PORT_TYPE);
        /*DMPS_DB_SET_PROPERTY_UPDATE(port_info, DMPS_DB_PORT_IF_TYPE);*/
        DMPS_DB_SET_PROPERTY_UPDATE(port_info, GET_DP_ID_BY_DIR(dir));
        DMPS_DB_SET_PROPERTY_UPDATE(port_info, GET_SUB_CHAN_ID_BY_DIR(dir));
        DMPS_DB_SET_PROPERTY_UPDATE(port_info, GET_MAC_CLIENT_ID_BY_DIR(dir));
        DMPS_DB_SET_PROPERTY_UPDATE(port_info, DMPS_DB_PSD_OCS);
        DMPS_DB_SET_PROPERTY_UPDATE(port_info, DMPS_DB_PORT_IF_MODE);
        DMPS_DB_SET_PROPERTY_UPDATE(port_info, GET_SPEED_MODE_BY_DIR(dir));
        CTC_ERROR_RETURN(sys_usw_dmps_db_get_port_info(lchip, &port_info));
        DMPS_DB_GET_MAP_INFO(port_info, DMPS_DB_DPORT,                      dport);
        DMPS_DB_GET_MAP_INFO(port_info, DMPS_DB_MAC_ID,                     mac_id);
        DMPS_DB_GET_PROPERTY_INFO(port_info, DMPS_DB_PORT_TYPE,             port_type);
        /*DMPS_DB_GET_PROPERTY_INFO(port_info, DMPS_DB_PORT_IF_TYPE,          if_type);*/
        DMPS_DB_GET_PROPERTY_INFO(port_info, GET_DP_ID_BY_DIR(dir),         dp);
        /*DMPS_DB_GET_PROPERTY_INFO(port_info, GET_SUB_CHAN_ID_BY_DIR(dir),   dp_chan);*/
        DMPS_DB_GET_PROPERTY_INFO(port_info, GET_MAC_CLIENT_ID_BY_DIR(dir), mac_client);
        DMPS_DB_GET_PROPERTY_INFO(port_info, DMPS_DB_PSD_OCS,               ocs);
        DMPS_DB_GET_PROPERTY_INFO(port_info, DMPS_DB_PORT_IF_MODE,          if_mode);
        DMPS_DB_GET_PROPERTY_INFO(port_info, GET_SPEED_MODE_BY_DIR(dir),    speed_mode);

        SYS_CONDITION_CONTINUE(dp != dp_id);
        SYS_CONDITION_CONTINUE((SYS_TMG_TXQM_NUM_PER_DP > dp_txqm_id) && 
            (SYS_TMG_GET_DP_TXQM_BY_MAC_ID(mac_id) != dp_txqm_id));
        if(port_type != SYS_DMPS_NETWORK_PORT)
        {
            SYS_CONDITION_CONTINUE((!is_cpumac_cal) || (!SYS_USW_IS_CPUMAC_PORT(port_type)));
        }

        /*xpipe check*/
        if(0 == xpipe_dual)
        {
            CTC_ERROR_RETURN(sys_usw_dmps_db_get_relative_id(lchip, DMPS_DB_TYPE_PORT, dport, GET_CHAN_TYPE_BY_DIR(dir), &p_chan_num, p_chan_id));
            SYS_CONDITION_CONTINUE(chan_id != p_chan_id[p_chan_num - 1]);
        }

        /*get basic speed*/
        if(CTC_CHIP_SERDES_OCS_MODE_12_58G == ocs)
        {
            /*12.96875G*4 enlarge speed*/
            speed = (CTC_CHIP_SERDES_XLG_MODE == if_mode) ? 50 : 15;
        }
        else
        {
            SYS_DATAPATH_MODE_TO_SPEED(speed_mode, speed);
        }

        if(is_mac_fix)
        {
            switch(if_mode)
            {
                case CTC_CHIP_SERDES_SGMII_MODE:
                    speed = 10;
                    break;
                case CTC_CHIP_SERDES_2DOT5G_MODE:
                    /*2.5G only support in 1050M & 800M*/
                    ///TODO: need confirm
                    CTC_ERROR_RETURN(sys_usw_dmps_db_get_core_pll(lchip, &core_pll, 1));
                    speed = (925 == core_pll) ? 25 : 20;
                    break;
                default:
                    break;
            }
        }

        dp_mac_client = SYS_TMG_GET_DP_MAC_CLIENT(mac_client);

        cal_info[dp_mac_client].cl_type = SYS_ALLOC_NORMAL;
        cal_info[dp_mac_client].chan_id = chan_id;
        cal_info[dp_mac_client].lport   = dport;
        cal_info[dp_mac_client].speed   = speed;
    }

    /*uint32 ii;
    printf("\n\n");
    for(ii = 0; ii < SYS_TMG_MAC_CLIENT_NUM_PER_DP; ii++)
    {
        printf("mac %u: cl_type %u, lport %u, chan_id %u, speed %u\n", ii, cal_info[ii].cl_type, cal_info[ii].lport, cal_info[ii].chan_id, cal_info[ii].speed);
    }
    printf("\n\n");*/

    return CTC_E_NONE;
}

int32
sys_tmg_datapath_get_extport_start_id(uint8 lchip, uint16* p_lport_start)
{
    *p_lport_start = SYS_INTERNAL_PORT_START;

    return CTC_E_NONE;
}

int32
_sys_tmg_datapath_get_lport_chan_by_serdes(uint8 lchip, uint16 logic_serdes, uint16* p_chan, uint16* p_dport)
{
    uint16 chan_idx = 0;
    uint8  occupy_flag = 0;
    uint16 lsd         = 0;
    uint16 dport       = 0;

    for(chan_idx = 0; chan_idx < SYS_TMG_CHANNEL_NUM; chan_idx++)
    {
        SYS_CONDITION_CONTINUE(CTC_E_NONE != sys_usw_dmps_db_get_chan2lsd(lchip, 0, chan_idx, &occupy_flag, &lsd, &dport));
        SYS_CONDITION_CONTINUE(SYS_DP_CHAN_LPORT_OCCUPY_RSV == occupy_flag);
        
        if(logic_serdes == lsd)
        {
            SYS_USW_VALID_PTR_WRITE(p_chan, chan_idx);
            SYS_USW_VALID_PTR_WRITE(p_dport,dport);

            return CTC_E_NONE;
        }
    }

    SYS_USW_VALID_PTR_WRITE(p_chan,  DMPS_INVALID_VALUE_U16);
    SYS_USW_VALID_PTR_WRITE(p_dport, DMPS_INVALID_VALUE_U16);
    
    return CTC_E_INVALID_CONFIG;
}

int32
_sys_tmg_datapath_get_serdes_chan_by_lport(uint8 lchip, uint16 dport, uint16* p_chan, uint16* p_logic_serdes)
{
    uint16 chan_idx = 0;
    uint8  occupy_flag = 0;
    uint16 lsd         = 0;
    uint16 dport_tmp   = 0;

    for(chan_idx = 0; chan_idx < SYS_TMG_CHANNEL_NUM; chan_idx++)
    {
        SYS_CONDITION_CONTINUE(CTC_E_NONE != sys_usw_dmps_db_get_chan2lsd(lchip, 0, chan_idx, &occupy_flag, &lsd, &dport_tmp));
        SYS_CONDITION_CONTINUE(SYS_DP_CHAN_LPORT_OCCUPY_RSV == occupy_flag);
        
        if(dport == dport_tmp)
        {
            SYS_USW_VALID_PTR_WRITE(p_chan, chan_idx);
            SYS_USW_VALID_PTR_WRITE(p_logic_serdes, lsd);
            return CTC_E_NONE;
        }
    }

    SYS_USW_VALID_PTR_WRITE(p_chan,  DMPS_INVALID_VALUE_U16);
    SYS_USW_VALID_PTR_WRITE(p_logic_serdes, DMPS_INVALID_VALUE_U16);

    return CTC_E_INVALID_CONFIG;
}

///TODO: get_misc_loop_chan
int32
_sys_tmg_datapath_get_misc_loop_chan(uint8 lchip, uint8 dp_id, uint16 sub_chan_id, uint16* chan_id, uint8 dir)
{
    return CTC_E_NONE;
}


/* check band-width in changing */
int32
_sys_tmg_datapath_check_bw(uint8 lchip, uint8 dp_id, uint8 dp_txqm, sys_dmps_change_chan_info_t* info, uint8 dir)
{
    uint8  speed_mode  = 0;
    uint8  port_type   = 0;
    uint8  chan_num    = 0;
    uint16 dport       = 0;
    uint16 chan_id     = 0;
    uint16 dp_chan     = 0;
    uint16 txqm_bw     = 0;
    uint16 speed       = 0;
    uint16 tmp_txqm    = 0;
    uint16 tmp_dp_txqm = 0;
    uint16 chan_list[DMPS_MAX_NUM_PER_MODULE] = {0};
    sys_dmps_db_upt_info_t port_info          = {0};

    /* get txqm bw before changing */
    for(dp_chan = 0; dp_chan < SYS_TMG_CHANNEL_NUM_PER_DP; dp_chan++)
    {
        chan_id = SYS_TMG_DPCHAN_TO_CHANNEL(dp_chan, dp_id);
        CTC_ERROR_RETURN(sys_usw_dmps_db_upt_info_init(lchip, &port_info));
        DMPS_DB_SET_MAP_INFO(port_info, DMPS_DB_CHAN_ID, chan_id);
        DMPS_DB_SET_PROPERTY_INFO(port_info, DMPS_DB_CHAN_SPEED_MODE, 0);
        DMPS_DB_SET_PROPERTY_INFO(port_info, DMPS_DB_PORT_TYPE,       0);
        DMPS_DB_SET_PROPERTY_INFO(port_info, DMPS_DB_CHAN_TXQM_ID,    0);
        CTC_ERROR_RETURN(sys_usw_dmps_db_get_port_info(lchip, &port_info));
        DMPS_DB_GET_MAP_INFO(port_info, DMPS_DB_DPORT, dport);
        DMPS_DB_GET_PROPERTY_INFO(port_info, DMPS_DB_CHAN_SPEED_MODE, speed_mode);
        DMPS_DB_GET_PROPERTY_INFO(port_info, DMPS_DB_PORT_TYPE,       port_type);
        DMPS_DB_GET_PROPERTY_INFO(port_info, DMPS_DB_CHAN_TXQM_ID,    tmp_txqm);
        tmp_dp_txqm = SYS_TMG_GET_DP_TXQM_BY_TXQM(tmp_txqm);
        SYS_CONDITION_CONTINUE(tmp_dp_txqm != dp_txqm);
        SYS_CONDITION_CONTINUE((!sys_usw_dmps_db_is_valid_id(lchip, DMPS_DB_TYPE_PORT, dport))
            || (SYS_DMPS_NETWORK_PORT != port_type));

        CTC_ERROR_RETURN(sys_usw_dmps_db_get_relative_id(lchip, DMPS_DB_TYPE_PORT, dport, GET_CHAN_TYPE_BY_DIR(dir), &chan_num, chan_list));
        if (chan_id != chan_list[0])
        {
            continue;
        }
        
        SYS_DATAPATH_MODE_TO_SPEED(speed_mode, speed);
        txqm_bw += speed;
    }

    /* get txqm bw after changing */
    for (chan_num = 0; chan_num < info->src_chan_num; chan_num++)
    {
        chan_id = info->src_chan_list[chan_num];
        CTC_ERROR_RETURN(sys_usw_dmps_db_upt_info_init(lchip, &port_info));
        DMPS_DB_SET_MAP_INFO(port_info, GET_CHAN_ID_BY_DIR(dir), chan_id);
        DMPS_DB_SET_PROPERTY_UPDATE(port_info, GET_SPEED_MODE_BY_DIR(dir));
        CTC_ERROR_RETURN(sys_usw_dmps_db_get_port_info(lchip, &port_info));
        DMPS_DB_GET_PROPERTY_INFO(port_info, GET_SPEED_MODE_BY_DIR(dir), speed_mode);
        SYS_DATAPATH_MODE_TO_SPEED(speed_mode, speed);
        txqm_bw -= speed;
    }

    SYS_DATAPATH_MODE_TO_SPEED(info->dst_speed_mode, speed);
    txqm_bw += (info->dst_chan_num * speed);

    SYS_DATAPATH_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "%% After change, txqm bw is %d\n", txqm_bw);

    if (txqm_bw > 200)
    {
        SYS_DATAPATH_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "%% BW of dp %d dp_txqm_id %d is lager than 200G! \n", dp_id, dp_txqm);
        return CTC_E_INVALID_CONFIG;
    }

    return CTC_E_NONE;
}

/* check credit in changing */
int32
_sys_tmg_datapath_check_credit(uint8 lchip, uint8 dp_id, uint8 dp_txqm, sys_dmps_change_chan_info_t* info, uint8 dir)
{
    uint8  speed_mode  = 0;
    uint8  port_type   = 0;
    uint8  mac_client  = 0;
    uint16 dp_chan     = 0;
    uint16 chan_id     = 0;
    uint16 chan_num    = 0;
    uint16 dport       = 0;
    uint16 speed       = 0;
    uint16 sub_chan    = 0;
    uint16 txqm_cli    = 0;
    uint16 credit      = 0;
    uint32 sum_qmgr    = 0;
    uint32 sum_brsop   = 0;
    uint32 sum_brbdy   = 0;
    uint32 sum_epe     = 0;
    uint32 sum_nettx   = 0;
    uint16 tmp_txqm    = 0;
    uint16 tmp_dp_txqm = 0;
    uint16 txqm_speed[SYS_TMG_MAC_CLIENT_NUM_PER_TXQM] = {0};    /* txqm speed list, without cpumac, misc, loop */
    uint16 dp_speed[SYS_TMG_CHANNEL_NUM_PER_DP]        = {0};    /* dp   speed list, with    cpumac, misc, loop */
    //- uint8  prio[SYS_TMG_CHANNEL_NUM_PER_DP]             = {0};    /* dp   prio list */
    sys_datapath_bufsz_step_t  step                    = {0};
    sys_dmps_db_upt_info_t port_info                   = {0};

    for(dp_chan = 0; dp_chan < SYS_TMG_CHANNEL_NUM_PER_DP; dp_chan++)
    {
        chan_id = SYS_TMG_DPCHAN_TO_CHANNEL(dp_chan, dp_id);

        SYS_CONDITION_CONTINUE(FALSE == sys_usw_dmps_db_is_valid_id(lchip, GET_CHAN_TYPE_BY_DIR(dir), chan_id));

        CTC_ERROR_RETURN(sys_usw_dmps_db_upt_info_init(lchip, &port_info));
        DMPS_DB_SET_MAP_INFO(port_info, GET_CHAN_ID_BY_DIR(dir), chan_id);
        DMPS_DB_SET_PROPERTY_UPDATE(port_info, GET_SPEED_MODE_BY_DIR(dir));
        DMPS_DB_SET_PROPERTY_UPDATE(port_info, GET_SUB_CHAN_ID_BY_DIR(dir));
        DMPS_DB_SET_PROPERTY_UPDATE(port_info, GET_MAC_CLIENT_ID_BY_DIR(dir));
        DMPS_DB_SET_PROPERTY_UPDATE(port_info, GET_TXQM_ID_BY_DIR(dir));
        DMPS_DB_SET_PROPERTY_UPDATE(port_info, GET_PRIO_BY_DIR(dir));
        DMPS_DB_SET_PROPERTY_UPDATE(port_info, DMPS_DB_PORT_TYPE);
        CTC_ERROR_RETURN(sys_usw_dmps_db_get_port_info(lchip, &port_info));
        DMPS_DB_GET_MAP_INFO(port_info, DMPS_DB_DPORT, dport);
        DMPS_DB_GET_PROPERTY_INFO(port_info, GET_SPEED_MODE_BY_DIR(dir),    speed_mode);
        DMPS_DB_GET_PROPERTY_INFO(port_info, GET_SUB_CHAN_ID_BY_DIR(dir),   sub_chan);
        DMPS_DB_GET_PROPERTY_INFO(port_info, GET_MAC_CLIENT_ID_BY_DIR(dir), mac_client);
        DMPS_DB_GET_PROPERTY_INFO(port_info, GET_TXQM_ID_BY_DIR(dir),       tmp_txqm);
        DMPS_DB_GET_PROPERTY_INFO(port_info, DMPS_DB_PORT_TYPE,             port_type);
        tmp_dp_txqm = SYS_TMG_GET_DP_TXQM_BY_TXQM(tmp_txqm);

        SYS_DATAPATH_MODE_TO_SPEED(speed_mode, speed);
        dp_speed[sub_chan] = speed;
        //- prio[sub_chan]   = prio_p;

        SYS_CONDITION_CONTINUE(tmp_dp_txqm != dp_txqm);
        SYS_CONDITION_CONTINUE((!sys_usw_dmps_db_is_valid_id(lchip, DMPS_DB_TYPE_PORT, dport))
            || (SYS_DMPS_NETWORK_PORT != port_type));

        txqm_speed[mac_client % SYS_TMG_MAC_CLIENT_NUM_PER_TXQM] = speed;
    }

    /* misc chan */
    CTC_ERROR_RETURN(_sys_tmg_datapath_get_misc_loop_chan(lchip, dp_id, SYS_TMG_MISC_CHAN_ID_IN_DP, &chan_id, dir));
    if (sys_usw_dmps_db_is_valid_id(lchip, GET_CHAN_TYPE_BY_DIR(dir), chan_id))
    {
        CTC_ERROR_RETURN(sys_usw_dmps_db_upt_info_init(lchip, &port_info));
        DMPS_DB_SET_MAP_INFO(port_info, GET_CHAN_ID_BY_DIR(dir), chan_id);
        DMPS_DB_SET_PROPERTY_UPDATE(port_info, GET_SPEED_MODE_BY_DIR(dir));
        DMPS_DB_SET_PROPERTY_UPDATE(port_info, GET_PRIO_BY_DIR(dir));
        CTC_ERROR_RETURN(sys_usw_dmps_db_get_port_info(lchip, &port_info));
        DMPS_DB_GET_PROPERTY_INFO(port_info, GET_SPEED_MODE_BY_DIR(dir),    speed_mode);
        SYS_DATAPATH_MODE_TO_SPEED(speed_mode, speed);
        dp_speed[SYS_TMG_MISC_CHAN_ID_IN_DP] = speed;
    }

    /* loop chan */
    CTC_ERROR_RETURN(_sys_tmg_datapath_get_misc_loop_chan(lchip, dp_id, SYS_TMG_LOOP_CHAN_ID_IN_DP, &chan_id, dir));
    if (sys_usw_dmps_db_is_valid_id(lchip, GET_CHAN_TYPE_BY_DIR(dir), chan_id))
    {
        CTC_ERROR_RETURN(sys_usw_dmps_db_upt_info_init(lchip, &port_info));
        DMPS_DB_SET_MAP_INFO(port_info, GET_CHAN_ID_BY_DIR(dir), chan_id);
        DMPS_DB_SET_PROPERTY_UPDATE(port_info, GET_SPEED_MODE_BY_DIR(dir));
        DMPS_DB_SET_PROPERTY_UPDATE(port_info, GET_PRIO_BY_DIR(dir));
        CTC_ERROR_RETURN(sys_usw_dmps_db_get_port_info(lchip, &port_info));
        DMPS_DB_GET_PROPERTY_INFO(port_info, GET_SPEED_MODE_BY_DIR(dir),    speed_mode);
        SYS_DATAPATH_MODE_TO_SPEED(speed_mode, speed);
        dp_speed[SYS_TMG_LOOP_CHAN_ID_IN_DP] = speed;
    }

    /* clear speed of change channel */
    for (chan_num = 0; chan_num < info->src_chan_num; chan_num++)
    {
        chan_id = info->src_chan_list[chan_num];

        CTC_ERROR_RETURN(sys_usw_dmps_db_upt_info_init(lchip, &port_info));
        DMPS_DB_SET_MAP_INFO(port_info, GET_CHAN_ID_BY_DIR(dir), chan_id);
        DMPS_DB_SET_PROPERTY_UPDATE(port_info, GET_SUB_CHAN_ID_BY_DIR(dir));
        DMPS_DB_SET_PROPERTY_UPDATE(port_info, GET_MAC_CLIENT_ID_BY_DIR(dir));
        DMPS_DB_SET_PROPERTY_UPDATE(port_info, DMPS_DB_PORT_TYPE);
        CTC_ERROR_RETURN(sys_usw_dmps_db_get_port_info(lchip, &port_info));
        DMPS_DB_GET_MAP_INFO(port_info, DMPS_DB_DPORT, dport);
        DMPS_DB_GET_PROPERTY_INFO(port_info, GET_SUB_CHAN_ID_BY_DIR(dir),     sub_chan);
        DMPS_DB_GET_PROPERTY_INFO(port_info, GET_MAC_CLIENT_ID_BY_DIR(dir),   mac_client);
        DMPS_DB_GET_PROPERTY_INFO(port_info, DMPS_DB_PORT_TYPE, port_type);

        dp_speed[sub_chan] = 0;

        SYS_CONDITION_CONTINUE((!sys_usw_dmps_db_is_valid_id(lchip, DMPS_DB_TYPE_PORT, dport))
            || (SYS_DMPS_NETWORK_PORT != port_type));

        txqm_speed[mac_client % SYS_TMG_MAC_CLIENT_NUM_PER_TXQM] = 0;
    }

    SYS_DATAPATH_MODE_TO_SPEED(info->dst_speed_mode, speed);

    /* add speed of new channel */
    for (chan_num = 0; chan_num < info->dst_chan_num; chan_num++)
    {
        chan_id = info->dst_chan_list[chan_num];

        CTC_ERROR_RETURN(sys_usw_dmps_db_upt_info_init(lchip, &port_info));
        DMPS_DB_SET_MAP_INFO(port_info, GET_CHAN_ID_BY_DIR(dir), chan_id);
        DMPS_DB_SET_PROPERTY_UPDATE(port_info, GET_SUB_CHAN_ID_BY_DIR(dir));
        DMPS_DB_SET_PROPERTY_UPDATE(port_info, GET_MAC_CLIENT_ID_BY_DIR(dir));
        CTC_ERROR_RETURN(sys_usw_dmps_db_get_port_info(lchip, &port_info));
        DMPS_DB_GET_PROPERTY_INFO(port_info, GET_SUB_CHAN_ID_BY_DIR(dir),     sub_chan);
        DMPS_DB_GET_PROPERTY_INFO(port_info, GET_MAC_CLIENT_ID_BY_DIR(dir),   mac_client);
 
        dp_speed[sub_chan] = speed;

        if (sub_chan < SYS_TMG_CHANNEL_NUM_PER_DP)
        {
            txqm_speed[mac_client % SYS_TMG_MAC_CLIENT_NUM_PER_TXQM] = speed;
        }
    }

    if (CHAN_DIR_IS_TX(dir))
    {
        /* get credit sum of qmgr, br */
        for (sub_chan = 0; sub_chan < SYS_TMG_CHANNEL_NUM_PER_DP; sub_chan++)
        {
            credit = _sys_tmg_datapath_speedmode_to_qmgrcrdt(dp_speed[sub_chan]);
            sum_qmgr += credit;

            _sys_tmg_datapath_bufretrv_get_credit(lchip, dp_speed[sub_chan], &step);
            sum_brsop += step.sop_buf_num;
            sum_brbdy += step.body_buf_num;
        }

        /* get credit sum of epe, netTx */
        for (txqm_cli = 0; txqm_cli < SYS_TMG_MAC_CLIENT_NUM_PER_TXQM; txqm_cli++)
        {
            credit = _sys_tmg_datapath_epe_speed_to_credit(txqm_speed[txqm_cli]);
            sum_epe += credit;

            credit = SYS_TMG_GET_NETTX_CREDIT_FROM_SPEED(txqm_speed[txqm_cli]);
            sum_nettx += credit;
        }

        SYS_DATAPATH_DBG_OUT(CTC_DEBUG_LEVEL_INFO, "%% After change, sum_qmgr is %d, sum_brsop is %d,\
        sum_brbdy is %d, sum_epe is %d, sum_nettx is %d\n", sum_qmgr, sum_brsop, sum_brbdy, sum_epe, sum_nettx);
        /*qmgr credit per dp sum check (512 per dp)*/
        if (sum_qmgr > SYS_TMG_MAX_QMGR_CREDIT_PER_DP)
        {
            SYS_DATAPATH_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "%% QMgr credit mistake in changing! dp %u, sum is %d \n",
                dp_id, sum_qmgr);
            return CTC_E_INVALID_CONFIG;
        }
        /*bufretrv credit per dp sum check (sop: 1024 per dp, body: 768 per dp)*/
        if (sum_brsop > SYS_TMG_MAX_BR_SOP_CREDIT_PER_DP)
        {
            SYS_DATAPATH_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "%% BufRetrv sop credit mistake in changing! dp %u, sum is %d \n",
                dp_id, sum_brsop);
            return CTC_E_INVALID_CONFIG;
        }
        if (sum_brbdy > SYS_TMG_MAX_BR_BODY_CREDIT_PER_DP)
        {
            SYS_DATAPATH_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "%% BufRetrv body credit mistake in changing! dp %u, sum is %d \n",
                dp_id, sum_brbdy);
            return CTC_E_INVALID_CONFIG;
        }
        /*epe credit sum check (256 per TXQM)*/
        if (sum_epe > SYS_TMG_MAX_EPE_CREDIT_PER_TXQM)
        {
            SYS_DATAPATH_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "%% Epe credit mistake in changing! dp %u, dp_txqm %u, sum is %d \n",
                dp_id, dp_txqm, sum_epe);
            return CTC_E_INVALID_CONFIG;
        }
        /*nettx credit sum check (320 per TXQM)*/
        if (sum_nettx > SYS_TMG_MAX_NETTX_CREDIT_PER_TXQM)
        {
            SYS_DATAPATH_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "%% Nettx credit mistake in changing! dp %u, dp_txqm %u, sum is %d \n",
                dp_id, dp_txqm, sum_nettx);
            return CTC_E_INVALID_CONFIG;
        }
    }

    return CTC_E_NONE;
}

/* check calendar in changing */
int32
_sys_tmg_datapath_check_calendar(uint8 lchip, uint8 dp_id, uint8 dp_txqm, sys_dmps_change_chan_info_t* info, uint8 dir)
{
    int32   ret        = CTC_E_NONE;
    uint8   error      = TRUE;
    uint8   sub_chan   = 0;
    uint8   mac_client = 0;
    uint16* cal        = NULL;
    uint16  walk_end   = 0;
    uint16  chan_id    = 0;
    uint16  chan_num   = 0;
    uint16  speed      = 0;
    sys_cal_info_collect_t* cal_info = NULL;
    sys_dmps_db_upt_info_t port_info    = {0};

    cal = (uint16*)mem_malloc(MEM_DMPS_MODULE, SYS_TMG_MAX_CAL_LEN * sizeof(uint16));
    CTC_ERROR_GOTO((NULL == cal) ? CTC_E_NO_MEMORY : CTC_E_NONE, ret, RELEASE_PTR_RETURN_1);
    sal_memset(cal, 0xff, SYS_TMG_MAX_CAL_LEN * sizeof(uint16));

    cal_info = (sys_cal_info_collect_t*)mem_malloc(MEM_DMPS_MODULE,
        SYS_TMG_MAC_CLIENT_NUM_PER_DP * sizeof(sys_cal_info_collect_t));
    CTC_ERROR_GOTO((NULL == cal_info) ? CTC_E_NO_MEMORY : CTC_E_NONE, ret, RELEASE_PTR_RETURN_2);
    if (CHAN_DIR_IS_TX(dir))
    {
        /* 1.  check BufRetrv & Epe calendar, consider CPUMAC */
        /* 1.1 info collect */
        _sys_tmg_calendar_speed_info_collect(lchip, cal_info, dp_id, SYS_TMG_TXQM_NUM_PER_DP, SYS_DMPS_EPE_CAL);

        /* 1.2 update collect information */
        for (chan_num = 0; chan_num < info->src_chan_num; chan_num++)
        {
            chan_id = info->src_chan_list[chan_num];
            CTC_ERROR_RETURN(sys_usw_dmps_db_upt_info_init(lchip, &port_info));
            DMPS_DB_SET_MAP_INFO(port_info, DMPS_DB_CHAN_ID, chan_id);
            DMPS_DB_SET_PROPERTY_UPDATE(port_info, DMPS_DB_CHAN_SUB_CHAN_ID);
            CTC_ERROR_RETURN(sys_usw_dmps_db_get_port_info(lchip, &port_info));
            DMPS_DB_GET_PROPERTY_INFO(port_info, DMPS_DB_CHAN_SUB_CHAN_ID,   sub_chan);
            cal_info[sub_chan].speed = 0;
        }
        for (chan_num = 0; chan_num < info->dst_chan_num; chan_num++)
        {
            chan_id = info->dst_chan_list[chan_num];
            CTC_ERROR_RETURN(sys_usw_dmps_db_upt_info_init(lchip, &port_info));
            DMPS_DB_SET_MAP_INFO(port_info, DMPS_DB_CHAN_ID, chan_id);
            DMPS_DB_SET_PROPERTY_UPDATE(port_info, DMPS_DB_CHAN_SUB_CHAN_ID);
            CTC_ERROR_RETURN(sys_usw_dmps_db_get_port_info(lchip, &port_info));
            DMPS_DB_GET_PROPERTY_INFO(port_info, DMPS_DB_CHAN_SUB_CHAN_ID,   sub_chan);
            SYS_DATAPATH_MODE_TO_SPEED(info->dst_speed_mode, speed);
            cal_info[sub_chan].speed = speed;
        }

        /* 1.3 calender caculateion */
        ret = _sys_tmg_datapath_calculate_general_calendar_parser(lchip, dp_id, cal, &walk_end, cal_info);

        /* 1.4 check calendar */
        if ((CTC_E_NONE != ret) || (SYS_TMG_MAX_CAL_LEN <= walk_end))
        {
            SYS_DATAPATH_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "%% Calculation of BufRetrv calendar with cpumac error! dp %d\n", dp_id);
            ret = CTC_E_INVALID_CONFIG;
            goto RELEASE_PTR_RETURN_3;
        }
        sal_memset(cal, 0, SYS_TMG_MAX_CAL_LEN * sizeof(uint16));

        /* 2.  check NetTx calendar */
        /* cpumac is no need in nettx */
        if (dp_txqm >= SYS_TMG_TXQM_NUM_PER_DP)
        {
            ret = CTC_E_NONE;
            goto RELEASE_PTR_RETURN_3;
        }
        /* 2.1 info collect */
        _sys_tmg_calendar_speed_info_collect(lchip, cal_info, dp_id, dp_txqm, SYS_DMPS_NETTX_CAL);

        /* 2.2 update collect information */
        for (chan_num = 0; chan_num < info->src_chan_num; chan_num++)
        {
            chan_id = info->src_chan_list[chan_num];
            CTC_ERROR_RETURN(sys_usw_dmps_db_upt_info_init(lchip, &port_info));
            DMPS_DB_SET_MAP_INFO(port_info, DMPS_DB_CHAN_ID, chan_id);
            DMPS_DB_SET_PROPERTY_UPDATE(port_info, DMPS_DB_CHAN_MAC_CLIENT_ID);
            CTC_ERROR_RETURN(sys_usw_dmps_db_get_port_info(lchip, &port_info));
            DMPS_DB_GET_PROPERTY_INFO(port_info, DMPS_DB_CHAN_MAC_CLIENT_ID,   mac_client);
            cal_info[mac_client].speed = 0;
        }
        for (chan_num = 0; chan_num < info->dst_chan_num; chan_num++)
        {
            chan_id = info->dst_chan_list[chan_num];
            CTC_ERROR_RETURN(sys_usw_dmps_db_upt_info_init(lchip, &port_info));
            DMPS_DB_SET_MAP_INFO(port_info, DMPS_DB_CHAN_ID, chan_id);
            DMPS_DB_SET_PROPERTY_UPDATE(port_info, DMPS_DB_CHAN_MAC_CLIENT_ID);
            CTC_ERROR_RETURN(sys_usw_dmps_db_get_port_info(lchip, &port_info));
            DMPS_DB_GET_PROPERTY_INFO(port_info, DMPS_DB_CHAN_MAC_CLIENT_ID,   mac_client);
            SYS_DATAPATH_MODE_TO_SPEED(info->dst_speed_mode, speed);
            cal_info[mac_client].speed = speed;
        }

        /* 2.3 calender caculateion */
        ret = _sys_tmg_datapath_nettx_common_calendar(lchip, dp_id, dp_txqm, &error, &walk_end, cal, cal_info);

        /* 2.4 check calendar */
        if ((CTC_E_NONE != ret) || (SYS_TMG_NETTX_MAX_CAL_LEN_PER_TXQM  <= walk_end))
        {
            SYS_DATAPATH_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "%% Calculation of NetTx calendar with cpumac error! dp %d dp_txqm %d\n", dp_id, dp_txqm);
            ret = CTC_E_INVALID_CONFIG;
            goto RELEASE_PTR_RETURN_3;
        }
        sal_memset(cal, 0, SYS_TMG_MAX_CAL_LEN * sizeof(uint16));
    }

    if (CHAN_DIR_IS_RX(dir))
    {
        /* 3.  check NetRx calendar */
        /* 3.1 info collect */
        _sys_tmg_calendar_speed_info_collect(lchip, cal_info, dp_id, dp_txqm, SYS_DMPS_NETRX_CAL);
        /* 3.2 update collect information */
        for (chan_num = 0; chan_num < info->src_chan_num; chan_num++)
        {
            chan_id = info->src_chan_list[chan_num];
            CTC_ERROR_RETURN(sys_usw_dmps_db_upt_info_init(lchip, &port_info));
            DMPS_DB_SET_MAP_INFO(port_info, DMPS_DB_CHAN_RX_ID, chan_id);
            DMPS_DB_SET_PROPERTY_UPDATE(port_info, DMPS_DB_CHAN_RX_MAC_CLIENT_ID);
            CTC_ERROR_RETURN(sys_usw_dmps_db_get_port_info(lchip, &port_info));
            DMPS_DB_GET_PROPERTY_INFO(port_info, DMPS_DB_CHAN_RX_MAC_CLIENT_ID,   mac_client);
            cal_info[mac_client].speed = 0;
        }
        for (chan_num = 0; chan_num < info->dst_chan_num; chan_num++)
        {
            chan_id = info->dst_chan_list[chan_num];
            CTC_ERROR_RETURN(sys_usw_dmps_db_upt_info_init(lchip, &port_info));
            DMPS_DB_SET_MAP_INFO(port_info, DMPS_DB_CHAN_RX_ID, chan_id);
            DMPS_DB_SET_PROPERTY_UPDATE(port_info, DMPS_DB_CHAN_RX_MAC_CLIENT_ID);
            CTC_ERROR_RETURN(sys_usw_dmps_db_get_port_info(lchip, &port_info));
            DMPS_DB_GET_PROPERTY_INFO(port_info, DMPS_DB_CHAN_RX_MAC_CLIENT_ID,   mac_client);
            SYS_DATAPATH_MODE_TO_SPEED(info->dst_speed_mode, speed);
            cal_info[mac_client].speed = speed;
        }
        
        /* 3.3 calender caculateion */
        ret = _sys_tmg_datapath_calculate_general_calendar_parser(lchip, dp_id, cal, &walk_end, cal_info);

        /* 3.4 check calendar */
        if ((CTC_E_NONE != ret) || (SYS_TMG_MAX_CAL_LEN <= walk_end))
        {
            SYS_DATAPATH_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "%% Calculation of NetRx calendar with cpumac error! dp %d\n", dp_id);
            ret = CTC_E_INVALID_CONFIG;
            goto RELEASE_PTR_RETURN_3;
        }
    }

RELEASE_PTR_RETURN_3:
    mem_free(cal_info);
RELEASE_PTR_RETURN_2:
    mem_free(cal);
RELEASE_PTR_RETURN_1:
    return ret;
}

/* check the validity of datapath */
int32
_sys_tmg_datapath_check(uint8 lchip, uint8 dp_id, uint8 dp_txqm, sys_dmps_change_chan_info_t* info, uint8 dir, uint8 check_bw)
{
#if ((1 == SDK_WORK_PLATFORM) || defined(EMULATOR_ENV))
    //- return CTC_E_NONE;
#endif
    if (CHAN_DIR_IS_TX(dir))
    {
        if (check_bw)
        {
            /* 1. check band-width */
            CTC_ERROR_RETURN(_sys_tmg_datapath_check_bw(lchip, dp_id, dp_txqm, info, CHAN_DIR_TX));
        }

        /* 2. check credit */
        CTC_ERROR_RETURN(_sys_tmg_datapath_check_credit(lchip, dp_id, dp_txqm, info, CHAN_DIR_TX));

        /* 3. check calendar */
        CTC_ERROR_RETURN(_sys_tmg_datapath_check_calendar(lchip, dp_id, dp_txqm, info, CHAN_DIR_TX));
    }

    if (CHAN_DIR_IS_RX(dir))
    {
        if (check_bw)
        {
            /* 1. check band-width */
            CTC_ERROR_RETURN(_sys_tmg_datapath_check_bw(lchip, dp_id, dp_txqm, info, CHAN_DIR_RX));
        }

        /* 2. check credit */
        CTC_ERROR_RETURN(_sys_tmg_datapath_check_credit(lchip, dp_id, dp_txqm, info, CHAN_DIR_RX));

        /* 3. check calendar */
        CTC_ERROR_RETURN(_sys_tmg_datapath_check_calendar(lchip, dp_id, dp_txqm, info, CHAN_DIR_RX));
    }
    
    return CTC_E_NONE;
}

/* check the validity of dynamic switch */
int32
_sys_tmg_datapath_dynamic_switch_check(uint8 lchip, sys_dmps_ds_list_t* target)
{
    uint8  dp_id   = 0;
    uint8  txqm_id = 0;
    uint8  dp_txqm = 0; 
    uint16 chan_id = 0;
    sys_dmps_db_upt_info_t port_info  = {0};

    if (0 == target->chan_info.dst_chan_num)
    {
        return CTC_E_NONE;
    }

    chan_id = target->chan_info.dst_chan_list[0];
    SYS_CONDITION_RETURN((!sys_usw_dmps_db_is_usable_id(lchip, DMPS_DB_TYPE_CHAN, chan_id)), CTC_E_INVALID_CONFIG);

    CTC_ERROR_RETURN(sys_usw_dmps_db_upt_info_init(lchip, &port_info));
    DMPS_DB_SET_MAP_INFO(port_info, DMPS_DB_CHAN_ID, chan_id);
    DMPS_DB_SET_PROPERTY_INFO(port_info, DMPS_DB_CHAN_DP_ID,   0);
    DMPS_DB_SET_PROPERTY_INFO(port_info, DMPS_DB_CHAN_TXQM_ID, 0);
    CTC_ERROR_RETURN(sys_usw_dmps_db_get_port_info(lchip, &port_info));
    DMPS_DB_GET_PROPERTY_INFO(port_info, DMPS_DB_CHAN_DP_ID,   dp_id);
    DMPS_DB_GET_PROPERTY_INFO(port_info, DMPS_DB_CHAN_TXQM_ID, txqm_id);

    if (txqm_id == SYS_TMG_CPUMAC_TXQM_ID)
    {
        return CTC_E_NONE;
    }

    dp_txqm = SYS_TMG_GET_DP_TXQM_BY_TXQM(txqm_id);

    CTC_ERROR_RETURN(_sys_tmg_datapath_check(lchip, dp_id, dp_txqm, &(target->chan_info), CHAN_DIR_TXRX, TRUE));

    return CTC_E_NONE;
}

int32
_sys_tmg_datapath_resource_alloc_chan(uint8 lchip, uint16 chan_id, uint8 enable, uint8 dir, uint8 is_xpipe)
{
    uint16  speed                     = 0;
    uint16 dp_txqm                    = 0;
    //-uint16 dp_mac_client              = 0;
    uint16 dp_chan                    = 0;
    uint16 dp_mac_id                  = 0;
    //-uint32 total_bw                   = 0;
    sys_dmps_db_chan_info_t chan_info = {0};

    chan_info.chan_id = chan_id;
    dp_chan =  SYS_TMG_CHANNEL_TO_DPCHAN(chan_id);
    
    if (CHAN_DIR_IS_TX(dir))
    {
        CTC_ERROR_RETURN(sys_usw_dmps_db_get_chan_info(lchip, &chan_info, CHAN_DIR_TX));
        
        //-dp_mac_client = SYS_TMG_GET_DP_MAC_CLIENT(chan_info.mac_client_id);
        dp_txqm       = SYS_TMG_GET_DP_TXQM_BY_TXQM(chan_info.txqm_id);
        SYS_DATAPATH_MODE_TO_SPEED(chan_info.speed_mode, speed);

        if (DMPS_INVALID_VALUE_U8 != chan_info.txqm_id)
        {
            /* network port */
            /* set nettx timer en */
            //total_bw = _sys_tmg_datapath_get_dp_bw(lchip, CHAN_DIR_TX, chan_info.dp_id);
            //CTC_ERROR_RETURN(_sys_tmg_datapath_set_nettx_timer(lchip, chan_info.dp_id, dp_mac_client, dp_txqm, speed, total_bw));

            if ((!is_xpipe) && (SYS_TMG_CPUMAC_TXQM_ID != chan_info.txqm_id))
            {
                /*set NetTx credit*/
                dp_mac_id = dp_txqm*SYS_TMG_MAX_MAC_NUM_PER_TXQM + SYS_TMG_GET_TXQM_MAC_CLIENT(chan_info.mac_client_id);
                CTC_ERROR_RETURN(_sys_tmg_datapath_set_nettx_credit(lchip, chan_info.dp_id, dp_mac_id, speed));
            }
        }

        /*set BufRetrv credit*/
        CTC_ERROR_RETURN(_sys_tmg_datapath_set_bufretrv_credit(lchip, chan_info.dp_id, dp_chan, chan_info.speed_mode));

        if (SYS_TMG_CPUMAC_TXQM_ID != chan_info.txqm_id)
        {
            /*set Epe credit*/
            CTC_ERROR_RETURN(_sys_tmg_datapath_set_epe_credit(lchip, chan_info.dp_id, chan_info.mac_client_id, chan_info.speed_mode));
        }

        /*set Qmgr credit*/
        CTC_ERROR_RETURN(_sys_tmg_datapath_set_qmgr_credit(lchip, chan_id, chan_info.speed_mode));
    }

    if (CHAN_DIR_IS_RX(dir))
    {
        CTC_ERROR_RETURN(sys_usw_dmps_db_get_chan_info(lchip, &chan_info, CHAN_DIR_RX));
    }

    return CTC_E_NONE;
}

int32
_sys_tmg_datapath_resource_alloc_group(uint8 lchip, uint8 dp_id, uint8 dp_txqm, uint8 is_nw, uint8 dir)
{
    uint8  dp_txqm_id                          = 0;
    uint8  port_type                           = 0;
    uint8  speed_mode                          = 0;
    uint32 speed                               = 0;
    uint16 mac_client                          = 0;
    uint16 dp_mac_client                       = 0;
    uint16 dp_chan                             = 0;
    uint16 chan_id                             = 0;
    uint32 total_bw                            = _sys_tmg_datapath_get_dp_bw(lchip, CHAN_DIR_TX, dp_id);
    uint16 wl_sum[SYS_TMG_TXQM_NUM_PER_DP]     = {0};
    uint16 wh_sum[SYS_TMG_TXQM_NUM_PER_DP]     = {0};
    uint16 wp[SYS_TMG_MAC_CLIENT_NUM_PER_TXQM] = {0};
    sys_dmps_db_upt_info_t port_info           = {0};
    
    /*set Epe, NetRx, BufRetrv calendar*/
    CTC_ERROR_RETURN(_sys_tmg_datapath_set_general_calendar(lchip, dp_id));

    if(CHAN_DIR_IS_TX(dir))
    {
        if (is_nw)
        {
            /*set NetTx calendar*/
            CTC_ERROR_RETURN(_sys_tmg_datapath_set_nettx_calendar(lchip, dp_id, dp_txqm));
        }

        /* set nettx timer en */
        for(dp_chan = 0; dp_chan < SYS_TMG_CHANNEL_NUM_PER_DP; dp_chan++)
        {
            chan_id = SYS_TMG_DPCHAN_TO_CHANNEL(dp_chan, dp_id);
            SYS_CONDITION_CONTINUE(FALSE == sys_usw_dmps_db_is_valid_id(lchip, DMPS_DB_TYPE_CHAN, chan_id));

            CTC_ERROR_RETURN(sys_usw_dmps_db_upt_info_init(lchip, &port_info));
            DMPS_DB_SET_MAP_INFO(port_info, DMPS_DB_CHAN_ID, chan_id);
            DMPS_DB_SET_PROPERTY_UPDATE(port_info, DMPS_DB_PORT_TYPE);
            DMPS_DB_SET_PROPERTY_UPDATE(port_info, DMPS_DB_CHAN_RX_SPEED_MODE);
            DMPS_DB_SET_PROPERTY_UPDATE(port_info, DMPS_DB_CHAN_MAC_CLIENT_ID);
            CTC_ERROR_RETURN(sys_usw_dmps_db_get_port_info(lchip, &port_info));
            DMPS_DB_GET_PROPERTY_INFO(port_info, DMPS_DB_PORT_TYPE,          port_type);
            DMPS_DB_GET_PROPERTY_INFO(port_info, DMPS_DB_CHAN_RX_SPEED_MODE, speed_mode);
            DMPS_DB_GET_PROPERTY_INFO(port_info, DMPS_DB_CHAN_MAC_CLIENT_ID, mac_client);

            /*NW only*/
            SYS_CONDITION_CONTINUE(port_type != SYS_DMPS_NETWORK_PORT);
            
            dp_mac_client = SYS_TMG_GET_DP_MAC_CLIENT(mac_client);
            SYS_DATAPATH_MODE_TO_SPEED(speed_mode, speed);

            CTC_ERROR_RETURN(_sys_tmg_datapath_set_nettx_timer(lchip, dp_id, dp_mac_client, dp_txqm, speed, total_bw));
        }

        /*set bufRetrv wrr weight*/
        CTC_ERROR_RETURN(_sys_tmg_datapath_set_bufretrv_wrr_weight(lchip, dp_id));

        /*set Epe wrr weight*/
        for(dp_txqm_id = 0; dp_txqm_id < SYS_TMG_TXQM_NUM_PER_DP; dp_txqm_id++)
        {
            CTC_ERROR_RETURN(_sys_tmg_datapath_epe_info_collect(lchip, dp_id, dp_txqm_id, 
                NULL, NULL, &(wl_sum[dp_txqm_id]), &(wh_sum[dp_txqm_id]), wp));

            CTC_ERROR_RETURN(_sys_tmg_datapath_epe_port_enable(lchip, dp_id, dp_txqm_id, 0xffff));
            /*config network port epe weight*/
            CTC_ERROR_RETURN(_sys_tmg_datapath_epe_nw_weight_cfg(lchip, dp_id, dp_txqm_id, wp));
        }
        CTC_ERROR_RETURN(_sys_tmg_datapath_epe_wrr_weight_cfg(lchip, dp_id, wl_sum, wh_sum));

        /*set Qmgr wrr weight*/
        CTC_ERROR_RETURN(_sys_tmg_datapath_qmgr_wrr_cfg(lchip));
    }

    if (CHAN_DIR_IS_RX(dir))
    {
        /*set NetRx wrr weight*/
        CTC_ERROR_RETURN(_sys_tmg_datapath_set_dp_netrx_cfg(lchip, dp_id));
    }
    
    return CTC_E_NONE;
}

int32
_sys_tmg_datapath_dynamic_switch_dp(uint8 lchip, sys_dmps_ds_list_t* target, uint8 dir_flag)
{
    uint8  dp_id    = 0;
    uint8  txqm_id  = 0;
    uint8  dp_txqm  = 0;
    uint8  chan_num = 0;
    uint8  sub_chan = 0;
    uint16 dp_chan  = 0;
    uint16 chan_id  = 0;
    uint16 lport    = 0;
    uint16 dport    = 0;
    uint16 lsd      = 0;
    sys_dmps_db_upt_info_t port_info  = {0};

    DP_DEBUG_FUNCTION_CALLED_PRINT();

    if (0 == target->chan_info.dst_chan_num)
    {
        chan_id = target->chan_info.src_chan_list[0];
    }
    else
    {
        chan_id = target->chan_info.dst_chan_list[0];
    }

    SYS_CONDITION_RETURN(!sys_usw_dmps_db_is_usable_id(lchip, DMPS_DB_TYPE_CHAN, chan_id), CTC_E_INVALID_CONFIG);
    CTC_ERROR_RETURN(sys_usw_dmps_db_upt_info_init(lchip, &port_info));
    DMPS_DB_SET_MAP_INFO(port_info, DMPS_DB_CHAN_ID, chan_id);
    DMPS_DB_SET_PROPERTY_UPDATE(port_info, DMPS_DB_CHAN_DP_ID);
    DMPS_DB_SET_PROPERTY_UPDATE(port_info, DMPS_DB_CHAN_TXQM_ID);
    DMPS_DB_SET_PROPERTY_UPDATE(port_info, DMPS_DB_CHAN_SUB_CHAN_ID);
    CTC_ERROR_RETURN(sys_usw_dmps_db_get_port_info(lchip, &port_info));
    DMPS_DB_GET_PROPERTY_INFO(port_info, DMPS_DB_CHAN_DP_ID,       dp_id);
    DMPS_DB_GET_PROPERTY_INFO(port_info, DMPS_DB_CHAN_TXQM_ID,     txqm_id);
    DMPS_DB_GET_PROPERTY_INFO(port_info, DMPS_DB_CHAN_SUB_CHAN_ID, sub_chan);

    dp_txqm = SYS_TMG_GET_DP_TXQM_BY_TXQM(txqm_id);

    /* 1. resource alloc by group */
    CTC_ERROR_RETURN(_sys_tmg_datapath_resource_alloc_group(lchip, dp_id, dp_txqm, SYS_TMG_IS_NW_CHAN(sub_chan),CHAN_DIR_TXRX));
    if ((txqm_id == SYS_TMG_CPUMAC_TXQM_ID) && (4 == target->chan_info.dst_chan_num))
    {
        dp_id   = SYS_TMG_GET_DP_ID_FROM_CHANID(target->chan_info.dst_chan_list[2]);
        CTC_ERROR_RETURN(_sys_tmg_datapath_resource_alloc_group(lchip, dp_id, dp_txqm, SYS_TMG_IS_NW_CHAN(sub_chan),CHAN_DIR_TXRX));
    }

    /* 2. resource alloc by chan */
    if (dir_flag)
    {
        /* dynamic_switch from none */
        for (chan_num = 0; chan_num < target->chan_info.dst_chan_num; chan_num++)
        {
            chan_id = target->chan_info.dst_chan_list[chan_num];
            CTC_ERROR_RETURN(_sys_tmg_datapath_resource_alloc_chan(lchip, chan_id, TRUE, CHAN_DIR_TXRX, FALSE));

            CTC_ERROR_RETURN(sys_usw_dmps_db_get_relative_id(lchip, DMPS_DB_TYPE_CHAN, chan_id, DMPS_DB_TYPE_LSD, NULL, &lsd));
            CTC_ERROR_RETURN(_sys_tmg_datapath_get_lport_chan_by_serdes(lchip, lsd, NULL, &dport));
            lport = dport; /*lport equals to dport, for bpe full mode*/
            if (DMPS_INVALID_VALUE_U16 != lport)
            {
                dp_chan = SYS_TMG_CHANNEL_TO_DPCHAN(chan_id);
                dp_id   = SYS_TMG_GET_DP_ID_FROM_CHANID(chan_id);
                CTC_ERROR_RETURN(_sys_tmg_datapath_set_map_by_chan(lchip, dp_id, dp_chan, CHAN_DIR_TXRX));
            }
        }
    }
    else
    {
        /* dynamic_switch to none */
        for (chan_num = 0; chan_num < target->chan_info.src_chan_num; chan_num++)
        {
            chan_id = target->chan_info.src_chan_list[chan_num];
            
            CTC_ERROR_RETURN(sys_usw_dmps_db_upt_info_init(lchip, &port_info));
            DMPS_DB_SET_MAP_INFO(port_info, DMPS_DB_CHAN_ID, chan_id);
            DMPS_DB_SET_PROPERTY_UPDATE(port_info, DMPS_DB_CHAN_SUB_CHAN_ID);
            CTC_ERROR_RETURN(sys_usw_dmps_db_get_port_info(lchip, &port_info));
            DMPS_DB_GET_PROPERTY_INFO(port_info, DMPS_DB_CHAN_SUB_CHAN_ID, sub_chan);
            CTC_ERROR_RETURN(_sys_tmg_datapath_resource_alloc_chan(lchip, chan_id, FALSE, CHAN_DIR_TXRX, FALSE));
        }
    }

    DP_DEBUG_FUNCTION_RETURN_PRINT();

    return CTC_E_NONE;
}

int32
_sys_tmg_datapath_mapping_cfg_to_none(uint8 lchip, uint16 src_dport)
{
    uint8  cnt                = 0;
    uint8  serdes_num         = 0;
    uint8  if_mode            = 0;
    uint8  port_type          = 0;
    uint8  tmp_mac_num        = 0;
    uint8  idx                = 0;
    uint16 psd                = 0;
    uint16 lsd                = 0;
    uint16 src_mac            = 0;
    uint16 src_pcs            = 0;
    uint16 src_lsd            = 0;
    uint16 src_chan           = 0;
    uint16 src_chan_rx        = 0;
    uint16 old_pcs_id         = 0;
    uint16 old_dport          = 0;
    uint16 old_lsd            = 0;
    uint16 old_psd            = 0;
    uint16 old_chan_id        = 0;
    uint16 tmp_mac[8]         = {0};
    sys_dmps_db_upt_info_t port_info  = {0};
    sys_dmps_db_upt_info_t upt_info_p = {0};

    if (!sys_usw_dmps_db_is_valid_id(lchip, DMPS_DB_TYPE_PORT, src_dport))
    {
        return CTC_E_INVALID_PARAM;
    }

    /* 1. get maping & db prop info */
    CTC_ERROR_RETURN(sys_usw_dmps_db_upt_info_init(lchip, &port_info));
    DMPS_DB_SET_MAP_INFO(port_info, DMPS_DB_DPORT, src_dport);
    DMPS_DB_SET_PROPERTY_UPDATE(port_info, DMPS_DB_PORT_IF_MODE);
    DMPS_DB_SET_PROPERTY_UPDATE(port_info, DMPS_DB_PORT_TYPE);
    CTC_ERROR_RETURN(sys_usw_dmps_db_get_port_info(lchip, &port_info));
    DMPS_DB_GET_MAP_INFO(port_info, DMPS_DB_MAC_ID,        src_mac);
    DMPS_DB_GET_MAP_INFO(port_info, DMPS_DB_PCS_ID,        src_pcs);
    DMPS_DB_GET_MAP_INFO(port_info, DMPS_DB_CHAN_ID,       src_chan);
    DMPS_DB_GET_MAP_INFO(port_info, DMPS_DB_CHAN_RX_ID,    src_chan_rx);
    DMPS_DB_GET_MAP_INFO(port_info, DMPS_DB_LOGIC_SERDES,  src_lsd);
    DMPS_DB_GET_PROPERTY_INFO(port_info, DMPS_DB_PORT_IF_MODE, if_mode);
    DMPS_DB_GET_PROPERTY_INFO(port_info, DMPS_DB_PORT_TYPE,    port_type);

    SYS_DMPS_GET_SERDES_NUM_BY_MODE(if_mode, serdes_num);
    if ((SYS_DMPS_NETWORK_PORT == port_type) || (SYS_DMPS_CPUMAC_NETWORK_PORT == port_type))
    {
        port_type = SYS_DMPS_RSV_PORT;
    }

    /* 2. set db prop to none */
    CTC_ERROR_RETURN(sys_usw_dmps_db_upt_info_init(lchip, &upt_info_p));
    DMPS_DB_SET_MAP_INFO(upt_info_p, DMPS_DB_DPORT,         src_dport);
    DMPS_DB_SET_MAP_INFO(upt_info_p, DMPS_DB_CHAN_ID,       src_chan);
    DMPS_DB_SET_MAP_INFO(upt_info_p, DMPS_DB_CHAN_RX_ID,    src_chan_rx);
    DMPS_DB_SET_PROPERTY_INFO(upt_info_p, DMPS_DB_PORT_IF_MODE,       CTC_CHIP_SERDES_NONE_MODE);
    DMPS_DB_SET_PROPERTY_INFO(upt_info_p, DMPS_DB_PORT_TYPE,          port_type);
    DMPS_DB_SET_PROPERTY_INFO(upt_info_p, DMPS_DB_PORT_IF_TYPE,       CTC_PORT_IF_NONE);
    DMPS_DB_SET_PROPERTY_INFO(upt_info_p, DMPS_DB_PORT_FEC_TYPE,      SYS_DMPS_FEC_TYPE_NONE);
    //- DMPS_DB_SET_PROPERTY_INFO(upt_info_p, DMPS_DB_PORT_SPEED_VALUE,   0);
    DMPS_DB_SET_PROPERTY_INFO(upt_info_p, DMPS_DB_PORT_LINK_FSM,      PMA_RX_NONREADY);
    DMPS_DB_SET_PROPERTY_INFO(upt_info_p, DMPS_DB_PORT_LINK_MODE,     g_port_link_mode);
    DMPS_DB_SET_PROPERTY_INFO(upt_info_p, DMPS_DB_CHAN_SPEED_MODE,    SYS_PORT_SPEED_MAX);
    DMPS_DB_SET_PROPERTY_INFO(upt_info_p, DMPS_DB_CHAN_RX_SPEED_MODE, SYS_PORT_SPEED_MAX);
    DMPS_DB_SET_PROPERTY_INFO(upt_info_p, DMPS_DB_PORT_IS_AN_FIRST,   0);
    CTC_ERROR_RETURN(sys_usw_dmps_db_set_port_info(lchip, &upt_info_p));

    /* 3. upd mapping node: delete dport & chan db from mapping node */
    for (cnt = 0; cnt < serdes_num; cnt++)
    {
        lsd = src_lsd + cnt;
        CTC_ERROR_RETURN(sys_usw_dmps_db_get_relative_id(lchip, DMPS_DB_TYPE_LSD, lsd,
            DMPS_DB_TYPE_PSD, NULL, &psd));

        CTC_ERROR_RETURN(sys_usw_dmps_db_upt_info_init(lchip, &upt_info_p));
        DMPS_DB_SET_MAP_UPDATE(upt_info_p);
        DMPS_DB_SET_MAP_INFO(upt_info_p, DMPS_DB_OLD_DPORT,         src_dport);
        DMPS_DB_SET_MAP_INFO(upt_info_p, DMPS_DB_OLD_MAC_ID,        src_mac);
        DMPS_DB_SET_MAP_INFO(upt_info_p, DMPS_DB_OLD_PCS_ID,        src_pcs);
        DMPS_DB_SET_MAP_INFO(upt_info_p, DMPS_DB_OLD_CHAN_ID,       src_chan);
        DMPS_DB_SET_MAP_INFO(upt_info_p, DMPS_DB_OLD_CHAN_RX_ID,    src_chan_rx);
        DMPS_DB_SET_MAP_INFO(upt_info_p, DMPS_DB_OLD_LOGIC_SERDES,  lsd);
        DMPS_DB_SET_MAP_INFO(upt_info_p, DMPS_DB_OLD_PHYSIC_SERDES, psd);

        DMPS_DB_SET_PROPERTY_UPDATE(upt_info_p, DMPS_DB_LSD_PCSL_IDX);
        DMPS_DB_SET_PROPERTY_UPDATE(upt_info_p, DMPS_DB_PSD_SPEED);

        DMPS_DB_SET_MAP_INFO(upt_info_p, DMPS_DB_MAC_ID,            src_mac + cnt);
        DMPS_DB_SET_MAP_INFO(upt_info_p, DMPS_DB_PCS_ID,            src_pcs + cnt);
        DMPS_DB_SET_MAP_INFO(upt_info_p, DMPS_DB_LOGIC_SERDES,      lsd);
        DMPS_DB_SET_MAP_INFO(upt_info_p, DMPS_DB_PHYSIC_SERDES,     psd);

        CTC_ERROR_RETURN(sys_usw_dmps_db_set_port_info(lchip, &upt_info_p));
    }

    /* 4. when port_num:serdes_num = N:1(N>1), delete redundant mapping node */
    CTC_ERROR_RETURN(sys_usw_dmps_db_get_relative_id(lchip, DMPS_DB_TYPE_LSD, lsd, DMPS_DB_TYPE_MAC, &tmp_mac_num, tmp_mac));
    for (idx = 1; idx < tmp_mac_num; idx ++)
    {
        CTC_ERROR_RETURN(sys_usw_dmps_db_upt_info_init(lchip, &port_info));
        DMPS_DB_SET_MAP_INFO(port_info, DMPS_DB_MAC_ID, tmp_mac[idx]);
        CTC_ERROR_RETURN(sys_usw_dmps_db_get_port_info(lchip, &port_info));
        DMPS_DB_GET_MAP_INFO(port_info, DMPS_DB_DPORT,         old_dport);
        DMPS_DB_GET_MAP_INFO(port_info, DMPS_DB_PCS_ID,        old_pcs_id);
        DMPS_DB_GET_MAP_INFO(port_info, DMPS_DB_PHYSIC_SERDES, old_psd);
        DMPS_DB_GET_MAP_INFO(port_info, DMPS_DB_LOGIC_SERDES,  old_lsd);
        DMPS_DB_GET_MAP_INFO(port_info, DMPS_DB_CHAN_ID,       old_chan_id);
    
        CTC_ERROR_RETURN(sys_usw_dmps_db_upt_info_init(lchip, &upt_info_p));
        DMPS_DB_SET_MAP_UPDATE(upt_info_p);
        DMPS_DB_SET_MAP_INFO(upt_info_p, DMPS_DB_OLD_DPORT,         old_dport);
        DMPS_DB_SET_MAP_INFO(upt_info_p, DMPS_DB_OLD_CHAN_ID,       old_chan_id);
        DMPS_DB_SET_MAP_INFO(upt_info_p, DMPS_DB_OLD_MAC_ID,        tmp_mac[idx]);
        DMPS_DB_SET_MAP_INFO(upt_info_p, DMPS_DB_OLD_PCS_ID,        old_pcs_id);
        DMPS_DB_SET_MAP_INFO(upt_info_p, DMPS_DB_OLD_LOGIC_SERDES,  old_lsd);
        DMPS_DB_SET_MAP_INFO(upt_info_p, DMPS_DB_OLD_PHYSIC_SERDES, old_psd);
        CTC_ERROR_RETURN(sys_usw_dmps_db_set_port_info(lchip, &upt_info_p));
    }

    return CTC_E_NONE;
}

int32
_sys_tmg_datapath_dynamic_switch_to_none(uint8 lchip, sys_dmps_ds_list_t* target, uint8 is_switch_serdes)
{   
    uint8  dport_num    = 0;
    uint8  lsd_num      = 0;
    uint16 logic_serdes = 0;
#if ((!defined(EMULATION_ENV) && (0 == SDK_WORK_PLATFORM)) || defined(TMG_SERDES_SIM))
    uint16 psd          = 0;
#endif
    uint16 mac_id       = 0;

    DP_DEBUG_FUNCTION_CALLED_PRINT();

    if (0 == target->src_dport_num)
    {
        return CTC_E_NONE;
    }

    for(dport_num = 0; dport_num < target->src_dport_num; dport_num++)
    {
        CTC_ERROR_RETURN(sys_tmg_mcu_del_port_mapping(lchip, target->src_dport_list[dport_num]));
    }

    /* 1. change database */
    for(dport_num = 0; dport_num < target->src_dport_num; dport_num++)
    {
        CTC_ERROR_RETURN(_sys_tmg_datapath_mapping_cfg_to_none(lchip, target->src_dport_list[dport_num]));
    }

#if ((!defined(EMULATION_ENV) && (0 == SDK_WORK_PLATFORM)) || defined(TMG_SERDES_SIM))
    if (is_switch_serdes)
    {
        /* TBD: 2. config serdes */
    
        for (lsd_num = 0; lsd_num < target->lsd_num; lsd_num++)
        {
            logic_serdes = target->lsd_list[lsd_num];
            CTC_ERROR_RETURN(sys_usw_dmps_db_get_relative_id(lchip, DMPS_DB_TYPE_LSD, logic_serdes, DMPS_DB_TYPE_PSD, NULL, &psd));
            CTC_ERROR_RETURN(_sys_tmg_serdes_speed_switch_proc(lchip, psd, SERDES_SPEED_0G));
        }
    }
#endif
    /* 3. config MAC/PCS/HATA register to NONE mode */
    for (lsd_num = 0; lsd_num < target->lsd_num; lsd_num++)
    {
        logic_serdes = target->lsd_list[lsd_num];
        CTC_ERROR_RETURN(sys_usw_dmps_db_get_relative_id(lchip, DMPS_DB_TYPE_LSD, logic_serdes, DMPS_DB_TYPE_MAC, NULL, &mac_id));
        CTC_ERROR_RETURN(_sys_tmg_mac_set_mac_config(lchip, mac_id));
    }

    /* 4. config datapath */
    CTC_ERROR_RETURN(_sys_tmg_datapath_dynamic_switch_dp(lchip, target, 0));

    DP_DEBUG_FUNCTION_RETURN_PRINT();

    return CTC_E_NONE;
}

int32
_sys_tmg_datapath_mapping_cfg_from_none(uint8 lchip, uint16 lsd, ctc_chip_serdes_mode_t dst_mode, uint8 ovclk)
{
    uint8 port_num = 0;
    uint8  serdes_num         = 0;
    uint8  idx                = 0;
    uint8  speed              = 0;
    uint8  if_type            = 0;
    uint8  fec_type           = 0;
    uint8  speed_mode         = 0;
    uint8  port_type          = 0;
    uint16 dport              = 0;
    uint16 mac_id             = 0;
    uint16 pcs_id             = 0;
    uint16 chan_id            = 0;
    uint16 tmp_chan_id   = 0;
    uint16 tmp_dport   = 0;
    uint16 psd                = 0;
    uint16 first_lsd          = 0;
    uint32 serdes_speed       = 0;
    uint32 support_speed      = 0;
    //- uint32 speed_value        = 0;
    sys_dmps_db_upt_info_t port_info  = {0};
    sys_dmps_db_upt_info_t upt_info_p = {0};
    sys_dmps_db_cpumac_map_t  p_map   = {0};

    SYS_DMPS_GET_SERDES_NUM_BY_MODE(dst_mode, serdes_num);

    if (0 == serdes_num)
    {
        return CTC_E_NONE;
    }

    /*1. param check */
    CTC_ERROR_RETURN(_sys_tmg_datapath_get_lport_chan_by_serdes(lchip, lsd, &chan_id, &dport));
    if ((!sys_usw_dmps_db_is_usable_id(lchip, DMPS_DB_TYPE_PORT, dport))
        || (!sys_usw_dmps_db_is_usable_id(lchip, DMPS_DB_TYPE_CHAN, chan_id))
        || (!sys_usw_dmps_db_is_usable_id(lchip, DMPS_DB_TYPE_CHAN_RX, chan_id)))
    {
        return CTC_E_INVALID_PARAM;
    }

    CTC_ERROR_RETURN(sys_usw_dmps_db_upt_info_init(lchip, &port_info));
    DMPS_DB_SET_MAP_INFO(port_info, DMPS_DB_DPORT, dport);
    DMPS_DB_SET_PROPERTY_UPDATE(port_info, DMPS_DB_PORT_TYPE);
    CTC_ERROR_RETURN(sys_usw_dmps_db_get_port_info(lchip, &port_info));
    DMPS_DB_GET_PROPERTY_INFO(port_info, DMPS_DB_PORT_TYPE, port_type);

    if (SYS_TMG_IS_NW_SERDES(lsd))
    {
        port_type = SYS_DMPS_NETWORK_PORT;
    }
    else if (SYS_TMG_IS_CPUMAC_NW_SERDES(lsd))
    {
        CTC_ERROR_RETURN(sys_usw_dmps_db_get_cpumac_map(lchip, lsd - SYS_TMG_MAX_SERDES_NUM_NW, &p_map));
        port_type = p_map.is_network ? SYS_DMPS_CPUMAC_NETWORK_PORT : SYS_DMPS_CPU_MAC_PORT;
    }

    /*2. get old mpping info */
    CTC_ERROR_RETURN(sys_usw_dmps_db_upt_info_init(lchip, &port_info));
    DMPS_DB_SET_MAP_INFO(port_info, DMPS_DB_LOGIC_SERDES, lsd);
    DMPS_DB_SET_PROPERTY_UPDATE(port_info, DMPS_DB_PSD_SUPPORT_SPEED);
    CTC_ERROR_RETURN(sys_usw_dmps_db_get_port_info(lchip, &port_info));
    DMPS_DB_GET_MAP_INFO(port_info, DMPS_DB_MAC_ID,        mac_id);
    DMPS_DB_GET_MAP_INFO(port_info, DMPS_DB_PCS_ID,        pcs_id);
    DMPS_DB_GET_MAP_INFO(port_info, DMPS_DB_PHYSIC_SERDES, psd);
    DMPS_DB_GET_PROPERTY_INFO(port_info, DMPS_DB_PSD_SUPPORT_SPEED, support_speed);

    if (SYS_DMPS_IS_PAM4_MODE(dst_mode))
    {
        fec_type = SYS_DMPS_FEC_TYPE_RS544;
    }
    else
    {
        fec_type = SYS_DMPS_FEC_TYPE_NONE;
    }

    /*3. upd mapping info */
    idx = lsd % serdes_num;
    if (0 == idx)
    {
        SYS_TMG_GET_PORT_IFTYPE(dst_mode,  if_type);
        SYS_DMPS_GET_PORT_SPEED(dst_mode, speed_mode);
        //- SYS_USW_GET_SPEED_VALUE(speed_mode, fec_type, ovclk, speed_value);

        CTC_ERROR_RETURN(sys_usw_dmps_db_upt_info_init(lchip, &upt_info_p));
        DMPS_DB_SET_MAP_INFO(upt_info_p, DMPS_DB_DPORT,         dport);
        DMPS_DB_SET_MAP_INFO(upt_info_p, DMPS_DB_CHAN_ID,       chan_id);
        DMPS_DB_SET_MAP_INFO(upt_info_p, DMPS_DB_CHAN_RX_ID,    chan_id);
        DMPS_DB_SET_PROPERTY_INFO(upt_info_p, DMPS_DB_PORT_IF_MODE,       dst_mode);
        DMPS_DB_SET_PROPERTY_INFO(upt_info_p, DMPS_DB_PORT_TYPE,          port_type);
        DMPS_DB_SET_PROPERTY_INFO(upt_info_p, DMPS_DB_PORT_IF_TYPE,       if_type);
        DMPS_DB_SET_PROPERTY_INFO(upt_info_p, DMPS_DB_PORT_FEC_TYPE,      fec_type);
        //- DMPS_DB_SET_PROPERTY_INFO(upt_info_p, DMPS_DB_PORT_SPEED_VALUE,   speed_value);
        DMPS_DB_SET_PROPERTY_INFO(upt_info_p, DMPS_DB_CHAN_SPEED_MODE,    speed_mode);
        DMPS_DB_SET_PROPERTY_INFO(upt_info_p, DMPS_DB_CHAN_RX_SPEED_MODE, speed_mode);
        CTC_ERROR_RETURN(sys_usw_dmps_db_set_port_info(lchip, &upt_info_p));
    }

    speed = sys_usw_dmps_get_speed_from_serdes_info(dst_mode, fec_type, ovclk);
    if (!((1 << speed) & support_speed))
    {
        SYS_DATAPATH_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, " %% Serdes %d cannot support this speed!  \n", psd);
        return CTC_E_INVALID_CONFIG;
    }
    SYS_USW_SERDES_SPEED_2_VALUE(speed, serdes_speed);

    first_lsd = lsd - idx;
    CTC_ERROR_RETURN(_sys_tmg_datapath_get_lport_chan_by_serdes(lchip, first_lsd, &tmp_chan_id, &tmp_dport));
    CTC_ERROR_RETURN(sys_usw_dmps_db_upt_info_init(lchip, &upt_info_p));
    DMPS_DB_SET_MAP_UPDATE(upt_info_p);
    DMPS_DB_SET_MAP_INFO(upt_info_p, DMPS_DB_OLD_MAC_ID,        mac_id);
    DMPS_DB_SET_MAP_INFO(upt_info_p, DMPS_DB_OLD_PCS_ID,        pcs_id);
    DMPS_DB_SET_MAP_INFO(upt_info_p, DMPS_DB_OLD_LOGIC_SERDES,  lsd);
    DMPS_DB_SET_MAP_INFO(upt_info_p, DMPS_DB_OLD_PHYSIC_SERDES, psd);
    DMPS_DB_SET_MAP_INFO(upt_info_p, DMPS_DB_DPORT,             tmp_dport);
    DMPS_DB_SET_MAP_INFO(upt_info_p, DMPS_DB_CHAN_ID,           tmp_chan_id);
    DMPS_DB_SET_MAP_INFO(upt_info_p, DMPS_DB_CHAN_RX_ID,        tmp_chan_id);
    DMPS_DB_SET_MAP_INFO(upt_info_p, DMPS_DB_MAC_ID,            mac_id  - idx);
    DMPS_DB_SET_MAP_INFO(upt_info_p, DMPS_DB_PCS_ID,            pcs_id  - idx);
    DMPS_DB_SET_MAP_INFO(upt_info_p, DMPS_DB_LOGIC_SERDES,      lsd);
    DMPS_DB_SET_MAP_INFO(upt_info_p, DMPS_DB_PHYSIC_SERDES,     psd);
    DMPS_DB_SET_PROPERTY_INFO(upt_info_p, DMPS_DB_LSD_PCSL_IDX, idx);
    DMPS_DB_SET_PROPERTY_INFO(upt_info_p, DMPS_DB_PSD_OCS,      ovclk);
    DMPS_DB_SET_PROPERTY_INFO(upt_info_p, DMPS_DB_PSD_SPEED,    serdes_speed);
    DMPS_DB_SET_PROPERTY_INFO(upt_info_p, DMPS_DB_PORT_IS_AN_FIRST,    0);
    DMPS_DB_SET_PROPERTY_INFO(upt_info_p, DMPS_DB_PORT_LINK_FSM,   PMA_RX_NONREADY);
    DMPS_DB_SET_PROPERTY_INFO(upt_info_p, DMPS_DB_PORT_LINK_MODE,  g_port_link_mode);
    CTC_ERROR_RETURN(sys_usw_dmps_db_set_port_info(lchip, &upt_info_p));
    if (lsd >= SYS_TMG_MAX_SERDES_NUM_NW)
    {
        (void) _sys_tmg_datapath_get_lport_chan_by_serdes(lchip, lsd, &p_map.chan_id, &p_map.lport);
        CTC_ERROR_RETURN(sys_usw_dmps_db_set_cpumac_map(lchip, lsd - SYS_TMG_MAX_SERDES_NUM_NW, &p_map));
    }

    /* 4. when port_num:serdes_num = N:1(N>1), need build mapping node */
    SYS_TMG_GET_PORT_NUM_BY_MODE(dst_mode,   port_num);
    for (idx = 1; idx < port_num; idx ++)
    {
        /* 4.1. set db prop */
        CTC_ERROR_RETURN(sys_usw_dmps_db_upt_info_init(lchip, &upt_info_p));
        DMPS_DB_SET_MAP_INFO(upt_info_p,      DMPS_DB_DPORT,           dport   + idx*SYS_TMG_ALLOC_MAC_STEP);
        DMPS_DB_SET_MAP_INFO(upt_info_p,      DMPS_DB_CHAN_ID,         chan_id + idx*SYS_TMG_ALLOC_MAC_STEP);
        DMPS_DB_SET_MAP_INFO(upt_info_p,      DMPS_DB_CHAN_RX_ID,      chan_id + idx*SYS_TMG_ALLOC_MAC_STEP);
        DMPS_DB_SET_MAP_INFO(upt_info_p,      DMPS_DB_LOGIC_SERDES,    lsd);
        DMPS_DB_SET_MAP_INFO(upt_info_p,      DMPS_DB_PHYSIC_SERDES,   psd);
        DMPS_DB_SET_MAP_INFO(upt_info_p,      DMPS_DB_MAC_ID,          mac_id + idx*SYS_TMG_ALLOC_MAC_STEP);
        DMPS_DB_SET_MAP_INFO(upt_info_p,      DMPS_DB_PCS_ID,          mac_id + idx*SYS_TMG_ALLOC_MAC_STEP);
        
        DMPS_DB_SET_PROPERTY_INFO(upt_info_p, DMPS_DB_PORT_IF_MODE,    dst_mode);
        DMPS_DB_SET_PROPERTY_INFO(upt_info_p, DMPS_DB_PORT_TYPE,       SYS_DMPS_NETWORK_PORT);
        DMPS_DB_SET_PROPERTY_INFO(upt_info_p, DMPS_DB_PORT_IF_TYPE,    if_type);
        DMPS_DB_SET_PROPERTY_INFO(upt_info_p, DMPS_DB_PORT_FEC_TYPE,   fec_type);
        /*SGMII default enable CL37 AN*/
        /*if(CTC_CHIP_SERDES_SGMII_MODE == dst_mode ||
           CTC_CHIP_SERDES_2DOT5G_MODE == dst_mode)
        {
            DMPS_DB_SET_PROPERTY_INFO(port_info, DMPS_DB_PORT_AN_EN, 1);    
        }*/
        DMPS_DB_SET_PROPERTY_INFO(upt_info_p, DMPS_DB_CHAN_SPEED_MODE, speed_mode);
        DMPS_DB_SET_PROPERTY_INFO(upt_info_p, DMPS_DB_CHAN_RX_SPEED_MODE, speed_mode);
        DMPS_DB_SET_PROPERTY_INFO(upt_info_p, DMPS_DB_LSD_PCSL_IDX,    0);
        DMPS_DB_SET_PROPERTY_INFO(upt_info_p, DMPS_DB_PSD_OCS,         ovclk);
        DMPS_DB_SET_PROPERTY_INFO(upt_info_p, DMPS_DB_PSD_SPEED,       serdes_speed);
        DMPS_DB_SET_PROPERTY_INFO(upt_info_p, DMPS_DB_PORT_IS_AN_FIRST,    0);
        DMPS_DB_SET_PROPERTY_INFO(upt_info_p, DMPS_DB_PORT_LINK_FSM,   PMA_RX_NONREADY);
        CTC_ERROR_RETURN(sys_usw_dmps_db_set_port_info(lchip, &upt_info_p));

        /* 4.2. build mapping node */
        CTC_ERROR_RETURN(sys_usw_dmps_db_upt_info_init(lchip, &upt_info_p));
        DMPS_DB_SET_MAP_UPDATE(upt_info_p);
        DMPS_DB_SET_MAP_INFO(upt_info_p, DMPS_DB_DPORT,             dport   + idx*SYS_TMG_ALLOC_MAC_STEP);
        DMPS_DB_SET_MAP_INFO(upt_info_p, DMPS_DB_CHAN_ID,           chan_id + idx*SYS_TMG_ALLOC_MAC_STEP);
        DMPS_DB_SET_MAP_INFO(upt_info_p, DMPS_DB_CHAN_RX_ID,        chan_id + idx*SYS_TMG_ALLOC_MAC_STEP);
        DMPS_DB_SET_MAP_INFO(upt_info_p, DMPS_DB_MAC_ID,            mac_id + idx*SYS_TMG_ALLOC_MAC_STEP);
        DMPS_DB_SET_MAP_INFO(upt_info_p, DMPS_DB_PCS_ID,            mac_id + idx*SYS_TMG_ALLOC_MAC_STEP);
        DMPS_DB_SET_MAP_INFO(upt_info_p, DMPS_DB_LOGIC_SERDES,      lsd);
        DMPS_DB_SET_MAP_INFO(upt_info_p, DMPS_DB_PHYSIC_SERDES,     psd);
        CTC_ERROR_RETURN(sys_usw_dmps_db_set_port_info(lchip, &upt_info_p)); 
        if (lsd >= SYS_TMG_MAX_SERDES_NUM_NW)
        {
            p_map.lport = dport   + idx*SYS_TMG_ALLOC_MAC_STEP;
            CTC_ERROR_RETURN(sys_usw_dmps_db_set_cpumac_map(lchip, lsd - SYS_TMG_MAX_SERDES_NUM_NW, &p_map));
        }
    }

    return CTC_E_NONE;
}

int32
_sys_tmg_datapath_dynamic_switch_from_none(uint8 lchip, sys_dmps_ds_list_t* target, uint8 is_switch_serdes)
{   
    uint8  lsd_num      = 0;
#if ((!defined(EMULATION_ENV) && (0 == SDK_WORK_PLATFORM)) || defined(TMG_SERDES_SIM))
    uint8 fec_type      = 0;
    uint8 serdes_speed  = 0;
#endif
    uint8  dport_num    = 0;
    uint16 psd          = 0;
    uint16 dport        = 0;
    uint16 mac_id       = 0;

    if (CTC_CHIP_SERDES_NONE_MODE == target->dst_mode)
    {
        return CTC_E_NONE;
    }

    DP_DEBUG_FUNCTION_CALLED_PRINT();

    /* 1. Update database */
    for (lsd_num = 0; lsd_num < target->lsd_num; lsd_num++)
    {
        CTC_ERROR_RETURN(_sys_tmg_datapath_mapping_cfg_from_none(lchip, target->lsd_list[lsd_num], target->dst_mode, target->ovclk));
    }

    /* 2. change database */
    for (dport_num = 0; dport_num < target->dst_dport_num; dport_num++)
    {
        dport = target->dst_dport_list[dport_num];
        /* TBD: config cut-through */
        //CTC_ERROR_RETURN(sys_usw_port_mac_config_attach(lchip, sys_usw_mac_get_lport_by_dport(lchip, dport)));
    }

    for(dport_num = 0; dport_num < target->dst_dport_num; dport_num++)
    {
        CTC_ERROR_RETURN(sys_tmg_mcu_add_port_mapping(lchip, target->dst_dport_list[dport_num]));
    }

    if (is_switch_serdes)
    {
        /* TBD: 3. config serdes */
#if ((!defined(EMULATION_ENV) && (0 == SDK_WORK_PLATFORM)) || defined(TMG_SERDES_SIM))
        for(lsd_num = 0; lsd_num < target->lsd_num; lsd_num++)
        {
            CTC_ERROR_RETURN(sys_usw_dmps_db_get_relative_id(lchip, DMPS_DB_TYPE_LSD, target->lsd_list[lsd_num], DMPS_DB_TYPE_PSD, NULL, &psd));
            fec_type = SYS_DMPS_IS_PAM4_MODE(target->dst_mode) ? SYS_DMPS_FEC_TYPE_RS544 : SYS_DMPS_FEC_TYPE_NONE;
            serdes_speed = sys_usw_dmps_get_speed_from_serdes_info(target->dst_mode, fec_type, target->ovclk);
            CTC_ERROR_RETURN(_sys_tmg_serdes_speed_switch_proc(lchip, psd, serdes_speed));
        }
#endif        
    }
    
    /* 4. config MAC/PCS/HATA register */
    for (dport_num = 0; dport_num < target->dst_dport_num; dport_num++)
    {
        dport = target->dst_dport_list[dport_num];
        CTC_ERROR_RETURN(sys_usw_dmps_db_get_relative_id(lchip, DMPS_DB_TYPE_PORT, dport, DMPS_DB_TYPE_MAC, NULL, &mac_id));
        CTC_ERROR_RETURN(_sys_tmg_mac_set_mac_config(lchip, mac_id));
    }
    
    /* 5. config datapath */
    CTC_ERROR_RETURN(_sys_tmg_datapath_dynamic_switch_dp(lchip, target, 1));

    /* 6. config cl73 init register */
    for(lsd_num = 0; lsd_num < target->lsd_num; lsd_num++)
    {
        CTC_ERROR_RETURN(sys_usw_dmps_db_get_relative_id(lchip, DMPS_DB_TYPE_LSD, target->lsd_list[lsd_num], DMPS_DB_TYPE_PSD, NULL, &psd));
        CTC_ERROR_RETURN(_sys_tmg_mac_cl73_reg_acc_init(lchip, psd, TRUE));
    }

    DP_DEBUG_FUNCTION_RETURN_PRINT();

    return CTC_E_NONE;
}

int32
_sys_tmg_datapath_dynamic_switch(uint8 lchip, sys_dmps_ds_list_t* target, uint8 is_switch_serdes)
{
    if (0 == target->lsd_num)
    {
        return CTC_E_NONE;
    }

    /* 1. switch to none */
    CTC_ERROR_RETURN(_sys_tmg_datapath_dynamic_switch_to_none(lchip, target, is_switch_serdes));

    /* 2. switch from none */
    CTC_ERROR_RETURN(_sys_tmg_datapath_dynamic_switch_from_none(lchip, target, is_switch_serdes));
    
    return CTC_E_NONE;
}

///TODO: same as TMM
void
_sys_tmg_datapath_sub_divisor(uint32 count, uint32 *p_speed, int16 *p_weight, int16 *weight_sum)
{
    uint16 index = 0;
    uint32 val = 0;
    uint32 max = 0;
    uint32 speed = 0;
    uint32 base = 0;
    uint32 common_div = 0;

    sal_memset(p_weight, 0, (sizeof(int16) * count));
    *weight_sum = 0;

    for(index = 0; index < count; index ++)
    {
        speed = *(p_speed + index);
        if(0 != speed)
        {
            max = speed;
            break;
        }
    }

    for(val = 1; val <= max; val ++)
    {
        common_div = 1;
        for(index = 0; index < count; index ++)
        {
            speed = *(p_speed + index);
            if(0 != (speed % val))
            {
                common_div = 0;   /*clear flag*/
                break;
            }
        }

        if(1 == common_div)
        {
            base = val;
        }
    }

    for(index = 0; index < count; index ++)
    {
        speed = *(p_speed + index);
        if((0 != speed) && (0 != base))
        {
            *(p_weight + index) = speed / base;
            *weight_sum += *(p_weight + index);
        }
    }

    return;
}


///TODO: same as TMM, except array len
int32 
_sys_tmg_datapath_common_calendar(int16 entry_num, uint32 count, uint32 *p_speed, uint8 *p_error, uint16 *p_walk_end, uint16 *p_cal)
{
    uint16 mac_idx           = 0;
    int16  index             = 0;
    uint16 max_id            = 0;
    int16  weight_sum        = 0;
    int16  max_weight        = 0;
    int16 *p_weight_list     = NULL;
    int16 *p_weight_list_org = NULL;
    uint8  high_prio_list[SYS_TMG_MAC_CLIENT_NUM_PER_DP] = {0};
    uint16 en[SYS_TMG_MAC_CLIENT_NUM_PER_DP]             = {0};

    SYS_DATAPATH_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s\n", __FUNCTION__);
    SYS_DATAPATH_DBG_OUT(CTC_DEBUG_LEVEL_PARAM,"entry_num %u, count %u\n", entry_num, count);

    /********************************************
     * common initial phase
     ********************************************/
    p_weight_list = (int16*)mem_malloc(MEM_DMPS_MODULE, count * sizeof(int16));
    if(NULL == p_weight_list)
    {
        return CTC_E_NO_MEMORY;
    }
    sal_memset(p_weight_list, 0, count * sizeof(int16));

    for(mac_idx = 0; mac_idx < count; mac_idx ++)
    {
        en[mac_idx] = (((*(p_speed + mac_idx)) > 0) ? 1 : 0);
    }

    /* calculate divisor */
    _sys_tmg_datapath_sub_divisor(count, p_speed, p_weight_list, &weight_sum);

    *p_walk_end = weight_sum - 1;
    if(weight_sum > entry_num)
    {
        *p_error = TRUE;
        goto RELEASE_PTR_RETURN;
    }
    else
    {
        *p_error = FALSE;
    }
    
    p_weight_list_org = (int16*)mem_malloc(MEM_DMPS_MODULE, count * sizeof(int16));
    if(NULL == p_weight_list_org)
    {
        goto RELEASE_PTR_RETURN;
    }
    sal_memcpy(p_weight_list_org, p_weight_list, (sizeof(int16) * count));

    for(mac_idx = 0; mac_idx < count; mac_idx ++)
    {
        /* if weight greater than 1, then add this port into high priority list */
        high_prio_list[mac_idx] = (p_weight_list[mac_idx] > 1 ? 1 : 0);
    }
    /********************************************
     * common initial phase
     ********************************************/
    for(index = 0; index < weight_sum; index ++)
    {
        /* look up max interval */
        max_weight = 0;
        max_id = 0;

        /*1. when there is an elements in the high_prio_list greater than zero,  look up max interval in high_prio_list*/
        for(mac_idx = 0; mac_idx < count; mac_idx ++)
        {
            if(high_prio_list[mac_idx] && en[mac_idx] && (max_weight < p_weight_list[mac_idx]))
            {
                max_weight = p_weight_list[mac_idx];
                max_id = mac_idx;
            }
        }

        /*2. when all elements in the high_prio_list less than zero,  look up max interval in p_weight_list*/
        if(max_weight == 0)
        {
            for(mac_idx = 0; mac_idx < count; mac_idx ++)
            {
                if(en[mac_idx] && (max_weight < p_weight_list[mac_idx]))
                {
                    max_weight = p_weight_list[mac_idx];
                    max_id = mac_idx;
                }
            }
        }

        p_cal[index] = max_id;
        
        p_weight_list[max_id] -= weight_sum;

        for(mac_idx = 0; mac_idx < count; mac_idx ++)
        {
            if(en[mac_idx])
            {
                p_weight_list[mac_idx] += p_weight_list_org[mac_idx];
            }
        }
    }
    mem_free(p_weight_list_org);

RELEASE_PTR_RETURN:
    mem_free(p_weight_list);

    return CTC_E_NONE; 
}

/*calendar indexed by mac_client [0~81]*/
int32
_sys_tmg_datapath_epe_netrx_common_calendar(uint8 lchip, uint8 dp_id, uint8 *p_error, 
                                                          uint16 *p_walk_end, uint16 *p_cal, sys_cal_info_collect_t* cal_info)
{
    int32  ret                  = CTC_E_NONE;
    uint16 cal_entry_num        = 512;
    uint16 mac_id_max           = SYS_TMG_MAC_CLIENT_NUM_PER_DP;
    uint16 core_pll             = 0;
    uint32 speed                = 0;
    uint32 speed_org            = 0;
    uint32 speed_2nd            = 0;
    uint32 speed_2nd_sum        = 0;
    uint32 speed_2nd_violation  = 0;
    uint32 speed_2nd_sum_max    = 0;
    uint32 dp_mac_idx           = 0;
    uint32 *speed_list          = NULL;
    uint32 *speed_list_2nd      = NULL;

    SYS_DATAPATH_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s\n", __FUNCTION__);
    SYS_DATAPATH_DBG_OUT(CTC_DEBUG_LEVEL_PARAM,"lchip %u, dp_id %u\n", lchip, dp_id);

    /********************************************
    * EpeSch common calendar 1st calculate
    ********************************************/
    speed_list = (uint32*)mem_malloc(MEM_DMPS_MODULE, mac_id_max * sizeof(uint32));
    if(NULL == speed_list)
    {
        return CTC_E_NO_MEMORY;
    }
    sal_memset(speed_list, 0, mac_id_max * sizeof(uint32));

    speed_list_2nd = (uint32*)mem_malloc(MEM_DMPS_MODULE, mac_id_max * sizeof(uint32));
    if(NULL == speed_list_2nd)
    {
        return CTC_E_NO_MEMORY;
    }
    sal_memset(speed_list_2nd, 0, mac_id_max * sizeof(uint32));

    /* stage1 : init speed list */
    for(dp_mac_idx = 0; dp_mac_idx < mac_id_max; dp_mac_idx ++)
    {
        /*get port speed*/
        speed_org = cal_info[dp_mac_idx].speed;

        speed = speed_org;
        speed_2nd = speed_org;

        //speed = (((speed_org > 0) && (speed_org < 1)) ? 1 : speed);
        speed_2nd = (((speed_org > 0) && (speed_org < 5)) ? 5 : speed_2nd);

        speed_list[dp_mac_idx] = ((2 == speed) ? 25 : (speed * 10));       /* 2.5G */
        speed_list_2nd[dp_mac_idx] = speed_2nd * 10;            /* x.5G */

        speed_2nd_sum += speed_list_2nd[dp_mac_idx];
    }

    /* stage2 : violation detect (very important !!!!!! ) */
    ///TODO: core pll relation?
    CTC_ERROR_RETURN(sys_usw_dmps_db_get_core_pll(lchip, &core_pll, 1));
    speed_2nd_sum_max = 10 * SYS_TMG_DP_BW_MAX * core_pll / SYS_TMG_CLK_DEFAULT;
    speed_2nd_violation = ((speed_2nd_sum > speed_2nd_sum_max) ? 1 : 0);

    /* stage3 : calculate calendar use common_calendar */
    if(speed_2nd_violation)
    {
        CTC_ERROR_GOTO(_sys_tmg_datapath_common_calendar(cal_entry_num, mac_id_max, speed_list, p_error, p_walk_end, p_cal), 
            ret, RELEASE_PTR_RETURN);
    }
    else
    {
        CTC_ERROR_GOTO(_sys_tmg_datapath_common_calendar(cal_entry_num, mac_id_max, speed_list_2nd, p_error, p_walk_end, p_cal), 
            ret, RELEASE_PTR_RETURN);
    }

    /* if PP is empty */
    if(0 == speed_2nd_sum)
    {
        *p_walk_end = 0;
    }

RELEASE_PTR_RETURN:
    mem_free(speed_list);
    mem_free(speed_list_2nd);
    return ret;
}
                                                          
///TODO: need change
int32
_sys_tmg_dp_calculate_interval(uint8 lchip, uint32 speed, uint32 num, uint8 low_prio, uint8 extra,
                               uint8 is_tx, uint32 bw_ratio, uint32* interval, uint32* p_cnt_sum)
{
    uint32 cnt = 0;
    uint32 avg_base = 0;
    uint32 avg_new = 0;
    uint32 cnt_org = 0;
    uint32 cnt_org_a1 = 0;
    uint32 cnt_sum = 0;
    uint32 cnt_sum_chg = 0;

    if(speed != 0)
    {
        if(is_tx)
        {
            /* division not at the end of the  expression wiil loss some accuracy */
            avg_base = bw_ratio * ((SYS_TMG_MAC_CALENDAR_BUS_WIDTH_TX*1 + 20 + 1)*8 ) * SYS_TMG_MAC_CALENDAR_CLK_MF /
                       (2 * 1000 * speed);
        }
        else
        {
            avg_base = bw_ratio * ((SYS_TMG_MAC_CALENDAR_BUS_WIDTH_EPE+20) * 8 ) * SYS_TMG_MAC_CALENDAR_CLK_MF /
                       (speed*1000);
        }
    }
    else
    {
        *interval = 0;
        return CTC_E_NONE;
    }

    cnt_org = avg_base / SYS_TMG_MAC_CALENDAR_MULTI_FACTOR;
    cnt_org_a1 = is_tx ? (cnt_org + 1) : cnt_org;

    if(low_prio || extra)
    {
        cnt = cnt_org_a1;
    }
    else if(num != 1)
    {
        cnt_sum = *p_cnt_sum;
        cnt_sum_chg = cnt_sum + cnt_org_a1;
        avg_new = (cnt_sum_chg * SYS_TMG_MAC_CALENDAR_MULTI_FACTOR) / num;
        cnt = (avg_new > avg_base) ? cnt_org : cnt_org_a1;
    }
    else
    {
        cnt = cnt_org;
    }

    *interval = cnt;
    *p_cnt_sum = cnt + cnt_sum;

    return CTC_E_NONE;
}

int32
_sys_tmg_datapath_calculate_general_calendar(uint8 lchip, uint8 optimize_cal, uint8 dp_id, 
                                                uint16* cal_epe, uint16* walk_end_epe, 
                                                uint8* p_error, uint32 mind_depth, sys_cal_info_collect_t* cal_info)
{
    uint8 txqm_id_0 = 0;
    uint8 p = 0;
    uint8 txqm_record = 0;
    uint16 speed_f = 0;
    uint8  mac_id_max = SYS_TMG_MAC_CLIENT_NUM_PER_DP;
    uint32* interval = NULL;/*interval,per port*/
    uint32* interval_cp = NULL;/*interval,per port*/
    uint32* interval_order = NULL;/*interval,per port*/
    uint16* portid_order = NULL;/*interval,per port*/
    uint32* num = NULL;/*select num ,per port*/
    uint8  active[SYS_TMG_MAC_CLIENT_NUM_PER_DP+1] = {0};/*active list*/
    uint8  en[SYS_TMG_MAC_CLIENT_NUM_PER_DP] = {0};/*port enable*/
    uint16* first_cal_record = NULL;/*record the index first select*/
    uint8  first_cal_record_en[SYS_TMG_MAC_CLIENT_NUM_PER_DP] = {0};/*record the index first select*/
    uint32 speed_sum = 0;
    uint32 speed = 0;
    uint32 oversub_bw = 1400;
    uint8  oversub_flag = FALSE;
    uint32 member_num = 0;
    uint32  bw_ratio = 1000;
    uint8  spd_2nd_lock = 0;
    uint8  spd_max_lock = 0;
    uint8  low_prio = FALSE;
    uint16 cycle    = 0;  /*calendar cycle*/
    uint8  done     = FALSE;
    uint16 min_id = 1;
    uint32 min_intv = 10000;
    uint16 min_index = 0;
    uint8  exchange_flag = 0;
    uint32 selport = 0;
    uint8  extra = FALSE;
    uint8  active_flag = FALSE;
    uint8  illegal = FALSE;
    uint8  reload_active = FALSE;
    uint8  i, k;
    
    uint32 actual_interval = 0;
    uint32 expect_interval = 0;
    uint32 multi_factor = 1000;
    uint32 speed_diff = 0;
    uint8 find_same_speed = FALSE;
    uint32 diff_speed_num = 0;
    uint32* speed_record = NULL;
    uint32 max_id;
    uint32 max_speed;
    uint32* speed_order = NULL;
    uint8 force_sel_epe = FALSE;
    uint8 force_sel = FALSE;

    uint32 last_gap = 0;
    uint16 mac_id;
    uint16 mac_id_tmp;
    uint32* cnt_history = NULL;
    uint8 txqm_RR = 0;
    
    uint32 speed_rate = 1;
    uint32 num_rate = 1;
    uint32 op_round = 1;
    uint32 speed_1st_num = 0;
    uint32 speed_2nd_num = 0;
    uint32 speed_1st = 0;
    uint32 speed_2nd;
    uint16 ooo;
    uint32 speed_ooo;
    uint32 speed_tx;
    int32  ret = CTC_E_NONE;

    /*per-txqm operation*/
    
    done = FALSE;
    /*error = FALSE;*/
    cycle = 0;
    speed_sum = 0;
    speed = 0;
    oversub_flag = FALSE;
    member_num = 0;
    bw_ratio = 1000;

    *p_error = 0;

    interval = (uint32*)mem_malloc(MEM_DMPS_MODULE, SYS_TMG_MAC_CLIENT_NUM_PER_DP * sizeof(uint32));
    CTC_ERROR_GOTO((NULL == interval) ? CTC_E_NO_MEMORY : CTC_E_NONE, ret, RELEASE_PTR_RETURN_1);
    sal_memset(interval, 0, SYS_TMG_MAC_CLIENT_NUM_PER_DP * sizeof(uint32));

    interval_cp = (uint32*)mem_malloc(MEM_DMPS_MODULE, (SYS_TMG_MAC_CLIENT_NUM_PER_DP + 1) * sizeof(uint32));
    CTC_ERROR_GOTO((NULL == interval_cp) ? CTC_E_NO_MEMORY : CTC_E_NONE, ret, RELEASE_PTR_RETURN_2);
    sal_memset(interval_cp, 0, (SYS_TMG_MAC_CLIENT_NUM_PER_DP + 1) * sizeof(uint32));

    interval_order = (uint32*)mem_malloc(MEM_DMPS_MODULE, SYS_TMG_MAC_CLIENT_NUM_PER_DP * sizeof(uint32));
    CTC_ERROR_GOTO((NULL == interval_order) ? CTC_E_NO_MEMORY : CTC_E_NONE, ret, RELEASE_PTR_RETURN_3);
    sal_memset(interval_order, 0, SYS_TMG_MAC_CLIENT_NUM_PER_DP * sizeof(uint32));

    num = (uint32*)mem_malloc(MEM_DMPS_MODULE, SYS_TMG_MAC_CLIENT_NUM_PER_DP * sizeof(uint32));
    CTC_ERROR_GOTO((NULL == num) ? CTC_E_NO_MEMORY : CTC_E_NONE, ret, RELEASE_PTR_RETURN_4);
    sal_memset(num, 0, SYS_TMG_MAC_CLIENT_NUM_PER_DP * sizeof(uint32));

    speed_order = (uint32*)mem_malloc(MEM_DMPS_MODULE, SYS_TMG_MAC_CLIENT_NUM_PER_DP * sizeof(uint32));
    CTC_ERROR_GOTO((NULL == speed_order) ? CTC_E_NO_MEMORY : CTC_E_NONE, ret, RELEASE_PTR_RETURN_5);
    sal_memset(speed_order, 0, SYS_TMG_MAC_CLIENT_NUM_PER_DP * sizeof(uint32));

    cnt_history = (uint32*)mem_malloc(MEM_DMPS_MODULE, SYS_TMG_MAC_CLIENT_NUM_PER_DP * sizeof(uint32));
    CTC_ERROR_GOTO((NULL == cnt_history) ? CTC_E_NO_MEMORY : CTC_E_NONE, ret, RELEASE_PTR_RETURN_6);
    sal_memset(cnt_history, 0, SYS_TMG_MAC_CLIENT_NUM_PER_DP * sizeof(uint32));

    speed_record = (uint32*)mem_malloc(MEM_DMPS_MODULE, SYS_TMG_MAC_CLIENT_NUM_PER_DP * sizeof(uint32));
    CTC_ERROR_GOTO((NULL == speed_record) ? CTC_E_NO_MEMORY : CTC_E_NONE, ret, RELEASE_PTR_RETURN_7);
    sal_memset(speed_record, 0, SYS_TMG_MAC_CLIENT_NUM_PER_DP * sizeof(uint32));

    portid_order = (uint16*)mem_malloc(MEM_DMPS_MODULE, SYS_TMG_MAC_CLIENT_NUM_PER_DP * sizeof(uint16));
    CTC_ERROR_GOTO((NULL == portid_order) ? CTC_E_NO_MEMORY : CTC_E_NONE, ret, RELEASE_PTR_RETURN_8);
    sal_memset(portid_order, 0, SYS_TMG_MAC_CLIENT_NUM_PER_DP * sizeof(uint16));

    first_cal_record = (uint16*)mem_malloc(MEM_DMPS_MODULE, SYS_TMG_MAC_CLIENT_NUM_PER_DP * sizeof(uint16));
    CTC_ERROR_GOTO((NULL == first_cal_record) ? CTC_E_NO_MEMORY : CTC_E_NONE, ret, RELEASE_PTR_RETURN_9);
    sal_memset(first_cal_record, 0, SYS_TMG_MAC_CLIENT_NUM_PER_DP * sizeof(uint16));

    /*initial phase*/
    for(i = 0; i < mac_id_max; i++)
    {
        mac_id = i;
        SYS_CONDITION_CONTINUE(SYS_ALLOC_NONE_MODE == cal_info[mac_id].cl_type);
        speed = cal_info[mac_id].speed;
        speed_sum += speed;
        first_cal_record[i] = 0;
        first_cal_record_en[i] = TRUE;
    }

    if(speed_sum > oversub_bw)
    {
        oversub_flag = 1;
    }
    /*else
    {
        bw_ratio = speed_sum*1000 / 1400;
    }*/

    /*look up low priority speed, inherit from Duet2*/
    /*spd_2nd_flag = FALSE;*/
    spd_2nd_lock = 0;
    spd_max_lock = 0;

    for(i = 0; i < mac_id_max; i++)
    {
        mac_id = i;
        SYS_CONDITION_CONTINUE(SYS_ALLOC_NONE_MODE == cal_info[mac_id].cl_type);
        speed_f = cal_info[mac_id].speed;
        
        if((speed_f != 0) && (speed_f > spd_max_lock))
        {
            spd_2nd_lock = spd_max_lock;
            spd_max_lock = speed_f;
        }

        if((speed_f != 0) && (speed_f > spd_2nd_lock) && (speed_f < spd_max_lock))
        {
            spd_2nd_lock = speed_f;
        }
    }

    /*look up different speed. for calendar optimization*/
    for(i = 0; i < mac_id_max; i++)
    {
        mac_id = i;
        SYS_CONDITION_CONTINUE(SYS_ALLOC_NONE_MODE == cal_info[mac_id].cl_type);
        speed_diff = cal_info[mac_id].speed;
        find_same_speed = FALSE;

        if(0 != speed_diff)
        {
            if(0 == diff_speed_num)
            {
                speed_record[0] = speed_diff;
                diff_speed_num++;
            }
            else
            {
                for(k = 0; k < diff_speed_num; k++)
                {
                    if(speed_record[k] == speed_diff)
                    {
                        find_same_speed = TRUE;
                    }
                }
                if(!find_same_speed)
                {
                    speed_record[diff_speed_num] = speed_diff;
                    diff_speed_num++;
                }
            }
        }
    }
    /*EPE speed array bubble sort begin*/
    for(k = 0; k < diff_speed_num; k++)
    {
        max_id = 1;
        max_speed = 0;
        for(i = 0; i < mac_id_max; i++)
        {
            if(max_speed < speed_record[i])
            {
                max_speed = speed_record[i];
                max_id = i;
            }
        }
        speed_record[max_id] = 0;
        speed_order[k] = max_speed;
    }
    
    for(i = 0; i < mac_id_max; i++)
    {
        mac_id = i;
        SYS_CONDITION_CONTINUE(SYS_ALLOC_NONE_MODE == cal_info[mac_id].cl_type);
        speed = cal_info[mac_id].speed;
        
        low_prio = oversub_flag && (spd_max_lock != speed);
        /*initial interval*/
        (void)_sys_tmg_dp_calculate_interval(lchip, speed, 1, low_prio, 0, 0, 
                                       bw_ratio, interval + i, &(cnt_history[mac_id]));
        /*initial active / enable and num*/
        if(1 <= speed)
        {
            active[i] = TRUE;
            en[i] = TRUE;
            num[i] = 1;
            member_num++;
        }
        else  /*invalid port*/
        {
            active[i] = FALSE;
            en[i] = FALSE;
            num[i] = 1;
            //member_num++;
        }
    }

    /*main function*/
    while((!done) && (!(*p_error)))
    {
        /*reorder*/
        for(i = 1; i <= mac_id_max; i++)
        {
            interval_cp[i] = interval[i-1];
        }
        /*stage1. bubble sort*/
        for(i = 1; i <= member_num; i++)
        {
            min_id = 1;
            min_intv = 10000;
            
            for(k = 1; k <= mac_id_max; k++)
            {
                if((interval_cp[k]) && (min_intv > interval_cp[k]))
                {
                    min_intv = interval_cp[k];
                    min_id = k;
                }
                else if((interval_cp[k]) && (min_intv == interval_cp[k]) && active[k])
                {
                    min_id = k;
                }
            }
            interval_cp[min_id] = 10000;
            interval_order[i] = min_intv;
            portid_order[i] = min_id - 1;
        }

        /*stage2. calendar select*/
        min_index = portid_order[1];  /*default min interval portid*/
        min_intv = interval_order[1];  /*default min interval*/
        /*detect error*/
        /*force_sel = FALSE;*/
        exchange_flag = FALSE;
        txqm_RR = (txqm_record == 3) ? 0 : txqm_record + 1;
        for(txqm_id_0 = 0; txqm_id_0 < 4; txqm_id_0++)
        {
            uint8 force_sel_txqm = 0;

            for(i = 1; i <= member_num; i++)
            {
               if(i > interval_order[i])
               {
                    *p_error = 2;
                    SYS_DATAPATH_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, 
                        "%% [general]automatic constrain failed! failed id = %u, interval = %u, cycle = %u\n", i, 
                        interval_order[i], cycle);
                    for(k = 1; k <= member_num; k++)
                    {
                        SYS_DATAPATH_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "%% [general]bubble sort index %u, interval %u\n", 
                            k, interval_order[k]);
                    }
                    break;
                } 
                /*get the mac id*/
                selport = portid_order[i];
                /*exchange min_index due to : 
                1: must in active list 
                2: doesn't set exchange_flag before 
                3: doesn't set force_sel before 
                4: has small interval*/
                if((active[selport]) && (!exchange_flag) && (!force_sel_txqm) && ((selport / 40) == txqm_RR))
                {
                    min_index = portid_order[i];
                    exchange_flag = TRUE;
                    min_intv = interval_order[i];
                }
            /*force_sel eq 1 means calendar can't select the portid_order index larger than i*/
                if(i == interval_order[i])
                {
                    /*force_sel = TRUE;*/
                    force_sel_txqm = TRUE;
                }
            }

            txqm_RR = (txqm_RR == 3) ? 0 : txqm_RR + 1;
        }

        /*stage2.2 loop up minIndex without TXQM RR condition*/
        force_sel_epe = 0;
        for(i = 1; i <= member_num; i++)
        {
            selport = portid_order[i];
            
            /*exchange minIndex due to : */
            /*1: must in active list */
            /*2: doesn't set exchange_flag before (may be assert by step2.1 and step2.2)*/
            /*3: doesn't set force_sel before */
            /*4: has small interval*/
            if(active[selport] && (!exchange_flag) && (!force_sel_epe))  /*epe calendar chg flag*/
            {
                min_index = portid_order[i];
                exchange_flag = TRUE;
                min_intv = interval_order[i];
            }
            /*if $force_sel_epe eq 1 ,means calendar can't select the portid_order index larger than i */
            if(i == interval_order[i])
            {
                force_sel = TRUE;
                force_sel_epe = TRUE; /*epe calendar chg flag*/
            }
        }

        /*stage3. maintain DS*/
        txqm_record = min_index / 40;
        /*stage3.1 all interval will decrease 1*/
        for(i = 0; i < mac_id_max; i++)
        {
            if(en[i])
            {
                interval[i]--;
            }
        }
        /*stage3.2 generage calendar data*/
        //cal[j][cycle] = min_index;
        cal_epe[cycle] = min_index;

        /*stage3.3  re-calulate interval*/
        mac_id = min_index;
        SYS_CONDITION_CONTINUE(SYS_ALLOC_NONE_MODE == cal_info[mac_id].cl_type);
        speed = cal_info[mac_id].speed;
        extra = (min_intv > 1) && force_sel;

        low_prio = oversub_flag && (spd_max_lock != speed);
        (void)_sys_tmg_dp_calculate_interval(lchip, speed, num[min_index], low_prio, extra, 0, 
                                       bw_ratio, interval + min_index, &(cnt_history[mac_id]));
        num[min_index]++;  /*num++ after re-calculate interval*/
        active[min_index] = FALSE;

        /*stage3.4 record the first calendar cycle*/
        if(first_cal_record_en[min_index])
        {
            first_cal_record[min_index] = cycle;
            first_cal_record_en[min_index] = FALSE;
        }

        /*stage4. finish calendar calculate*/
        /*4.1 detect active flag*/
        active_flag = FALSE;
        
        for(i = 0; i < mac_id_max; i++)
        {
            if(active[i])
            {
                active_flag = TRUE;
            }
        }
        /*4.2 detect interval violation*/
        /*NetTx use 1*192+1 Byte to calculate interval average*/
        if(!active_flag)
        {
            /*uint8 high_speed_num = 0;
            uint8 low_speed_num = 0;*/
                
            illegal = FALSE;
            /*mactx_illegal = 0;*/
            /*sal_memset(mactx_reorder_en, FALSE, SYS_TMM_MAX_MAC_NUM_PER_DP*sizeof(uint8));*/
            for(i = 0; i < mac_id_max; i++)
            {
                mac_id = i;
                SYS_CONDITION_CONTINUE(SYS_ALLOC_NONE_MODE == cal_info[mac_id].cl_type);
                speed_tx = cal_info[mac_id].speed;

                /*if(speed_tx == spd_max_lock)
                    high_speed_num = num[i] - 1;
                if(speed_tx == spd_2nd_lock)
                    low_speed_num = num[i] - 1;*/

                /*port enable*/
                if(0 != speed_tx)
                {
                    /*192*1+1 B could reach performance*/
                    ///TODO: need change
                    expect_interval = ((SYS_TMG_MAC_CALENDAR_BUS_WIDTH_EPE+20) * SYS_TMG_MAC_CALENDAR_CLK_MF * 8) / speed_tx;
                    actual_interval = (((uint32)cycle + 1) * multi_factor) / (num[i] - 1);
                    if(actual_interval > expect_interval)
                    {
                        illegal = TRUE;
                        active[i] = TRUE;
                    }
                    /*tail --> head gap illegal calculate*/
                    /*last_gap = first_cal_record[i];*/
                    last_gap = (first_cal_record[i] > 1) ? (first_cal_record[i] - 1) : 0;
                    last_gap = last_gap * bw_ratio / multi_factor;
                    if(last_gap > interval[i])
                    {
                        /*illegal = TRUE;
                        active[i] = TRUE;*/
                    }
                }
            }

            if(optimize_cal)
            {
                speed_rate = 1;
                num_rate = 1;
                op_round = 1;
                speed_1st_num = 0;
                speed_2nd_num = 0;

                if(1 < diff_speed_num)
                {
                    uint32 loop_cycle_max = (mind_depth > diff_speed_num) ? diff_speed_num : mind_depth;

                    for(op_round = 0; op_round <= loop_cycle_max-2; op_round++)
                    {
                        if(op_round == 0)
                        {
                            speed_1st = speed_order[op_round];
                        }
                        speed_2nd = speed_order[op_round+1];

                        for(ooo = 0; ooo < mac_id_max; ooo++)
                        {
                            mac_id_tmp = ooo;
                            SYS_CONDITION_CONTINUE(SYS_ALLOC_NONE_MODE == cal_info[mac_id_tmp].cl_type);
                            speed_ooo = cal_info[mac_id_tmp].speed;

                            if(speed_ooo == speed_1st)
                            {
                                speed_1st_num = num[ooo] - 1;
                            }
                            if(speed_ooo == speed_2nd)
                            {
                                speed_2nd_num = num[ooo] - 1;
                            }
                        }

                        SYS_CONDITION_CONTINUE((0 == speed_2nd) || (0 == speed_2nd_num));
                        speed_rate = 10 * speed_1st / speed_2nd;
                        num_rate = 10 * speed_1st_num / speed_2nd_num;

                        if(speed_rate > num_rate)
                        {
                            illegal = TRUE;
                            for(p = 0; p < mac_id_max; p++)
                            {
                                mac_id_tmp = p;
                                SYS_CONDITION_CONTINUE(SYS_ALLOC_NONE_MODE == cal_info[mac_id_tmp].cl_type);
                                speed_tx = cal_info[mac_id_tmp].speed;
                                if(speed_tx == speed_1st)
                                {
                                    active[p] = TRUE;
                                }
                            }
                            speed_1st = speed_2nd;
                        }
                        else if(speed_rate < num_rate)
                        {
                            illegal = TRUE;
                            for(p = 0; p < mac_id_max; p++)
                            {
                                mac_id_tmp = p;
                                SYS_CONDITION_CONTINUE(SYS_ALLOC_NONE_MODE == cal_info[mac_id_tmp].cl_type);
                                speed_tx = cal_info[mac_id_tmp].speed;
                                if(speed_tx == speed_2nd)
                                {
                                    active[p] = TRUE;
                                }
                            }
                        }
                        else
                        {
                            speed_1st = speed_2nd;
                        }
                    }
                }
            }

            reload_active = illegal;
            /*finish if no violation*/
            if(!reload_active)
            {
                done = TRUE;
                *walk_end_epe = cycle;
            }
        }
        cycle++;
        if(cycle >= SYS_TMG_MAX_CAL_LEN)
        {
            *p_error = 1;
        }
    }

    if(*p_error)
    {
        ret = CTC_E_INVALID_PARAM;
        goto RELEASE_PTR_RETURN_10;
    }
    
RELEASE_PTR_RETURN_10:
    mem_free(first_cal_record);
RELEASE_PTR_RETURN_9:
    mem_free(portid_order);
RELEASE_PTR_RETURN_8:
    mem_free(speed_record);
RELEASE_PTR_RETURN_7:
    mem_free(cnt_history);
RELEASE_PTR_RETURN_6:
    mem_free(speed_order);
RELEASE_PTR_RETURN_5:
    mem_free(num);
RELEASE_PTR_RETURN_4:
    mem_free(interval_order);
RELEASE_PTR_RETURN_3:
    mem_free(interval_cp);
RELEASE_PTR_RETURN_2:
    mem_free(interval);
RELEASE_PTR_RETURN_1:
    return ret;
}

int32
_sys_tmg_datapath_calculate_general_calendar_common(uint8 lchip, uint8 dp_id, uint16* cal, uint16* walk_end, 
                                                        uint8* p_error, sys_cal_info_collect_t* cal_info)
{
    uint16 i, j;
    uint16 max_id = 0;
    int32  max_weight = 0;
    uint32 weight_sum = 0;
    uint8  mac_id_max = SYS_TMG_MAC_CLIENT_NUM_PER_DP;
    uint16 speed_list[SYS_TMG_MAC_CLIENT_NUM_PER_DP] = {0};
    int32* weight_list = NULL;
    int32* weight_list_org = NULL;
    uint8  en[SYS_TMG_MAC_CLIENT_NUM_PER_DP] = {0};
    uint16 gcd = 0;
    int32  ret = CTC_E_NONE;

    weight_list = mem_malloc(MEM_DMPS_MODULE, sizeof(int32) * SYS_TMG_MAC_CLIENT_NUM_PER_DP);
    CTC_ERROR_GOTO((NULL == weight_list) ? CTC_E_NO_MEMORY : CTC_E_NONE, ret, RELEASE_PTR_RETURN_1);
    sal_memset(weight_list, 0, sizeof(int32) * SYS_TMG_MAC_CLIENT_NUM_PER_DP);

    weight_list_org = mem_malloc(MEM_DMPS_MODULE, sizeof(int32) * SYS_TMG_MAC_CLIENT_NUM_PER_DP);
    CTC_ERROR_GOTO((NULL == weight_list_org) ? CTC_E_NO_MEMORY : CTC_E_NONE, ret, RELEASE_PTR_RETURN_2);
    sal_memset(weight_list_org, 0, sizeof(int32) * SYS_TMG_MAC_CLIENT_NUM_PER_DP);

    SYS_USW_VALID_PTR_WRITE(p_error, 0);

    /*common initial phase*/
    for(i = 0; i < mac_id_max; i++)
    {
        speed_list[i] = cal_info[i].speed * 10;
        en[i] = (SYS_ALLOC_NONE_MODE == cal_info[i].cl_type) ? FALSE : TRUE;
    }
    
    /*calculate divisor*/
    CTC_ERROR_GOTO(sys_usw_datapath_get_gcd(speed_list, SYS_TMG_MAC_CLIENT_NUM_PER_DP, &gcd), 
        ret, RELEASE_PTR_RETURN_3);
    for(i = 0; i < mac_id_max; i++)
    {
        weight_list[i] = speed_list[i] / gcd;
        weight_sum += weight_list[i];
        weight_list_org[i] = weight_list[i];
    }

    if(weight_sum > SYS_TMG_MAX_CAL_LEN)
    {
        SYS_USW_VALID_PTR_WRITE(p_error, 1);
        ret = CTC_E_NONE;
        goto RELEASE_PTR_RETURN_3;
    }

    /*common calendar main function*/
    for(i = 0; i < weight_sum; i++)
    {
        max_weight = 0;
        max_id = 0;

        /*stage1. look up max interval*/
        for(j = 0; j < mac_id_max; j++)
        {
            if(en[j] && (max_weight < weight_list[j]))
            {
                max_weight = weight_list[j];
                max_id = j;
            }
        }
        cal[i] = max_id;

        /*stage2. common speed list update begin*/
        weight_list[max_id] -= weight_sum;
        for(j = 0; j < mac_id_max; j++)
        {
            if(en[j])
            {
                weight_list[j] += weight_list_org[j];
            }
        }
    }

    SYS_USW_VALID_PTR_WRITE(walk_end, (weight_sum-1));
    SYS_USW_VALID_PTR_WRITE(p_error, 0);
    
RELEASE_PTR_RETURN_3:
    mem_free(weight_list_org);
RELEASE_PTR_RETURN_2:
    mem_free(weight_list);
RELEASE_PTR_RETURN_1:
    return ret;
}

int32
_sys_tmg_datapath_calculate_general_calendar_parser(uint8 lchip, uint8 dp_id, uint16* cal, 
                                                    uint16* walk_end, sys_cal_info_collect_t* cal_info)
{
    uint32 mind_depth[] = {10, 3, 3};
    uint8  optimize_cal[] = {1, 1, 0};
    uint8  idx;
    uint8  error = TRUE;

    /*1. First Use new calendar algorithms*/
    sal_memset(cal, 0, SYS_TMG_MAX_CAL_LEN * sizeof(uint16));
    *walk_end = 0;

    /*If don't calculation, then use old common calculation*/
    _sys_tmg_datapath_epe_netrx_common_calendar(lchip, dp_id, &error, walk_end, cal, cal_info);
    if(!error)
    {
        return CTC_E_NONE;
    }

    sal_memset(cal, 0, SYS_TMG_MAX_CAL_LEN * sizeof(uint16));
    *walk_end = 0;
    _sys_tmg_datapath_calculate_general_calendar_common(lchip, dp_id, cal, walk_end, &error, cal_info);
    if(!error)
    {
        return CTC_E_NONE;
    }

    /*then try 3 times at most*/
    for(idx = 0; idx < 3; idx++)
    {
        sal_memset(cal, 0, SYS_TMG_MAX_CAL_LEN * sizeof(uint16));
        *walk_end = 0;
        error = 0;
        _sys_tmg_datapath_calculate_general_calendar(lchip, optimize_cal[idx], dp_id, cal, walk_end, 
                                                     &error, mind_depth[idx], cal_info);
        if(!error)
        {
            return CTC_E_NONE;
        }
    }

    SYS_DATAPATH_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "%% Calculation of general calendar error! dp_id %u\n", dp_id);
    return CTC_E_INVALID_PARAM;
}

int32
_sys_tmg_datapath_epe_cal_cfg(uint8 lchip, uint8 dp_id, const uint16* cal, uint16 walk_end)
{
    uint32 val_32 = 0;
    uint32 entry_id = 0;
    uint32 cmd = 0;
    uint16 i = 0;
    uint8  is_back_cal = 0;
    uint32 table = 0;
    uint32 field = 0;
    EpeScheduleCalendar0Ram_m epe_cal;
    EpeScheduleCalCtl_m cal_ctl;

    /*cfg EpeScheduleCalCtl*/
    entry_id = DRV_INS(dp_id, 0);
    
    cmd = DRV_IOR(EpeScheduleCalCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, entry_id, cmd, &cal_ctl));

    val_32 = GetEpeScheduleCalCtl(V, cfgCalUsedEn_f, &cal_ctl);
    is_back_cal = GetEpeScheduleCalCtl(V, cfgCalSelPtr_f, &cal_ctl);
    if(val_32 == 0) is_back_cal = 0;
    else            is_back_cal = is_back_cal ? 0 : 1;

    /*cfg EpeScheduleCalendar[0 1]Ram*/
    table = (is_back_cal ? EpeScheduleCalendar1Ram_t : EpeScheduleCalendar0Ram_t);
    field = (is_back_cal ? EpeScheduleCalendar1Ram_calPtr_f : EpeScheduleCalendar0Ram_calPtr_f);
    for(i = 0; i <= walk_end; i++)
    {
        entry_id = DRV_INS(dp_id, i);

        cmd = DRV_IOR(table, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, entry_id, cmd, &epe_cal));

        val_32 = cal[i];
        DRV_IOW_FIELD_NZ(lchip, table, field, &val_32, &epe_cal, dp_id, i);

        cmd = DRV_IOW(table, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, entry_id, cmd, &epe_cal));
    }

    /*WalkerEnd*/
    val_32 = walk_end;
    if(is_back_cal)
    {
        DRV_IOW_FIELD_NZ(lchip, EpeScheduleCalCtl_t, EpeScheduleCalCtl_cfgCal1WalkEndPtr_f,
            &val_32, &cal_ctl, dp_id, 0);
    }
    else
    {
        DRV_IOW_FIELD_NZ(lchip, EpeScheduleCalCtl_t, EpeScheduleCalCtl_cfgCal0WalkEndPtr_f,
            &val_32, &cal_ctl, dp_id, 0);
    }
    entry_id = DRV_INS(dp_id, 0);
    cmd = DRV_IOW(EpeScheduleCalCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, entry_id, cmd, &cal_ctl));

    /*BankSel*/
    cmd = DRV_IOR(EpeScheduleCalCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, entry_id, cmd, &cal_ctl));
    val_32 = 1;
    DRV_IOW_FIELD_NZ(lchip, EpeScheduleCalCtl_t, EpeScheduleCalCtl_cfgCalUsedEn_f, &val_32, &cal_ctl, dp_id, 0);
    val_32 = is_back_cal;
    DRV_IOW_FIELD_NZ(lchip, EpeScheduleCalCtl_t, EpeScheduleCalCtl_cfgCalSelPtr_f, &val_32, &cal_ctl, dp_id, 0);
    cmd = DRV_IOW(EpeScheduleCalCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, entry_id, cmd, &cal_ctl));

    return CTC_E_NONE;
}

int32
_sys_tmg_datapath_get_channel_by_mac_client(uint8 lchip, uint8 dir, uint8 dp, uint16 mac_client, uint16* p_chan_id)
{
    uint16 dp_chan            = 0;
    uint16 chan_id            = 0;
    uint16 tmp_mac_client     = 0;
    sys_dmps_db_upt_info_t port_info         = {0};

    for(dp_chan = 0; dp_chan < SYS_TMG_NW_CHAN_NUM_PER_DP; dp_chan++)
    {
        chan_id = SYS_TMG_CHANNEL_NUM_PER_DP*dp + dp_chan;
        SYS_CONDITION_CONTINUE(FALSE == sys_usw_dmps_db_is_valid_id(lchip, GET_CHAN_TYPE_BY_DIR(dir), chan_id));

        CTC_ERROR_RETURN(sys_usw_dmps_db_upt_info_init(lchip, &port_info));
        DMPS_DB_SET_MAP_INFO(port_info, GET_CHAN_ID_BY_DIR(dir), chan_id);
        DMPS_DB_SET_PROPERTY_UPDATE(port_info, GET_MAC_CLIENT_ID_BY_DIR(dir));
        CTC_ERROR_RETURN(sys_usw_dmps_db_get_port_info(lchip, &port_info));
        DMPS_DB_GET_PROPERTY_INFO(port_info, GET_MAC_CLIENT_ID_BY_DIR(dir), tmp_mac_client);

        if(tmp_mac_client == mac_client)
        {
            SYS_USW_VALID_PTR_WRITE(p_chan_id, chan_id);
            return CTC_E_NONE;
        }
    }

    return CTC_E_INVALID_PARAM;
}

int32
_sys_tmg_datapath_br_cal_cfg(uint8 lchip, uint8 dp_id, const uint16* cal, uint16 walk_end)
{
    uint32 val_32        = 0;
    uint32 entry_id      = 0;
    uint32 cmd           = 0;
    uint16 i             = 0;
    uint8  is_back_cal   = 0;
    uint16 chan_id       = 0;
    uint16 dp_chan_id    = 0;
    uint32 table_out_cal = 0;
    uint32 table_buf_cal = 0;
    uint32 field_out_cal = 0;
    uint32 field_buf_cal = 0;
    BufRetrvDPBufPtrCalendar0Mem_m buf_cal;
    BufRetrvDPWrrCtl_m             cal_ctl;

    entry_id = DRV_INS(dp_id, 0);
    
    cmd = DRV_IOR(BufRetrvDPWrrCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, entry_id, cmd, &cal_ctl));

    val_32 = GetBufRetrvDPWrrCtl(V, outDataCalEnable_f, &cal_ctl);
    is_back_cal = GetBufRetrvDPWrrCtl(V, bufPtrCalSel_f, &cal_ctl);
    if(val_32 == 0) is_back_cal = 0;
    else            is_back_cal = is_back_cal ? 0 : 1;

    if(is_back_cal)
    {
        table_out_cal = BufRetrvDPOutDataCalendar1Mem_t;
        table_buf_cal = BufRetrvDPBufPtrCalendar1Mem_t;
        field_out_cal = BufRetrvDPOutDataCalendar1Mem_chanId_f;
        field_buf_cal = BufRetrvDPBufPtrCalendar1Mem_chanId_f;
    }
    else
    {
        table_out_cal = BufRetrvDPOutDataCalendar0Mem_t;
        table_buf_cal = BufRetrvDPBufPtrCalendar0Mem_t;
        field_out_cal = BufRetrvDPOutDataCalendar0Mem_chanId_f;
        field_buf_cal = BufRetrvDPBufPtrCalendar0Mem_chanId_f;
    }

    for(i = 0; i <= walk_end; i++)
    {
        SYS_CONDITION_CONTINUE(CTC_E_NONE != _sys_tmg_datapath_get_channel_by_mac_client(lchip, CHAN_DIR_TX, 
            dp_id, cal[i], &chan_id));
        dp_chan_id = SYS_TMG_CHANNEL_TO_DPCHAN(chan_id);

        /*bufRetrvDPOutDataCalendarMem*/
        entry_id = DRV_INS(dp_id, i);
        cmd = DRV_IOR(table_out_cal, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, entry_id, cmd, &buf_cal));

        val_32 = dp_chan_id;
        DRV_IOW_FIELD_NZ(lchip, table_out_cal, field_out_cal, &val_32, &buf_cal, dp_id, i);

        cmd = DRV_IOW(table_out_cal, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, entry_id, cmd, &buf_cal));
            
        /*bufRetrvDPBufPtrCalendarMem*/
        entry_id = DRV_INS(dp_id, i);
        cmd = DRV_IOR(table_buf_cal, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, entry_id, cmd, &buf_cal));

        val_32 = dp_chan_id;
        DRV_IOW_FIELD_NZ(lchip, table_buf_cal, field_buf_cal, &val_32, &buf_cal, dp_id, i);

        cmd = DRV_IOW(table_buf_cal, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, entry_id, cmd, &buf_cal));
    }

    /*WalkerEnd*/
    if(is_back_cal)
    {
        val_32 = walk_end;
        DRV_IOW_FIELD_NZ(lchip, BufRetrvDPWrrCtl_t, BufRetrvDPWrrCtl_bufPtrCalWalkEndPtr1_f,
                &val_32, &cal_ctl, dp_id, 0);
        DRV_IOW_FIELD_NZ(lchip, BufRetrvDPWrrCtl_t, BufRetrvDPWrrCtl_outDataCalWalkEndPtr1_f,
                &val_32, &cal_ctl, dp_id, 0);
    }
    else
    {
        val_32 = walk_end;
        DRV_IOW_FIELD_NZ(lchip, BufRetrvDPWrrCtl_t, BufRetrvDPWrrCtl_bufPtrCalWalkEndPtr0_f,
                &val_32, &cal_ctl, dp_id, 0);
        DRV_IOW_FIELD_NZ(lchip, BufRetrvDPWrrCtl_t, BufRetrvDPWrrCtl_outDataCalWalkEndPtr0_f,
                &val_32, &cal_ctl, dp_id, 0);
    }
    entry_id = DRV_INS(dp_id, 0);
    cmd = DRV_IOW(BufRetrvDPWrrCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, entry_id, cmd, &cal_ctl));

    /*BankSel*/
    cmd = DRV_IOR(BufRetrvDPWrrCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, entry_id, cmd, &cal_ctl));

    /*WrrCtl*/
    val_32 = 1;
    DRV_IOW_FIELD_NZ(lchip, BufRetrvDPWrrCtl_t, BufRetrvDPWrrCtl_outDataCalEnable_f,
            &val_32, &cal_ctl, dp_id, 0);
    val_32 = 1;
    DRV_IOW_FIELD_NZ(lchip, BufRetrvDPWrrCtl_t, BufRetrvDPWrrCtl_bufPtrCalEnable_f,
            &val_32, &cal_ctl, dp_id, 0);
    val_32 = is_back_cal;
    DRV_IOW_FIELD_NZ(lchip, BufRetrvDPWrrCtl_t, BufRetrvDPWrrCtl_bufPtrCalSel_f,
            &val_32, &cal_ctl, dp_id, 0);
    val_32 = is_back_cal;
    DRV_IOW_FIELD_NZ(lchip, BufRetrvDPWrrCtl_t, BufRetrvDPWrrCtl_outDataCalSel_f,
            &val_32, &cal_ctl, dp_id, 0);   

    entry_id = DRV_INS(dp_id, 0);
    cmd = DRV_IOW(BufRetrvDPWrrCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, entry_id, cmd, &cal_ctl));
    
    return CTC_E_NONE;
}

uint32
_sys_tmg_datapath_netrx_cal_cfg(uint8 lchip, uint8 dp_id, const uint16* cal, uint16 walk_end)
{
    uint32 val_32 = 0;
    uint32 entry_id = 0;
    uint32 cmd = 0;
    uint16 i = 0;
    uint8  is_back_cal = 0;
    uint32 table = 0;
    uint32 field = 0;
    NetRxCalendar0_m netrx_cal;
    NetRxCalCtl_m cal_ctl;

    /*NetRxCalCtl*/
    entry_id = DRV_INS(dp_id, 0);
    
    cmd = DRV_IOR(NetRxCalCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, entry_id, cmd, &cal_ctl));

    val_32 = GetNetRxCalCtl(V, cfgCalUsedEn_f, &cal_ctl);
    is_back_cal = GetNetRxCalCtl(V, cfgCalSel_f, &cal_ctl);
    if(val_32 == 0) is_back_cal = 0;
    else            is_back_cal = is_back_cal ? 0 : 1;

    /*NetRxCalendar*/
    table = (is_back_cal ? NetRxCalendar1_t : NetRxCalendar0_t);
    field = (is_back_cal ? NetRxCalendar1_port_f : NetRxCalendar0_port_f);
    for(i = 0; i <= walk_end; i++)
    {       
        entry_id = DRV_INS(dp_id, i);
        cmd = DRV_IOR(table, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, entry_id, cmd, &netrx_cal));

        val_32 = cal[i];
        DRV_IOW_FIELD_NZ(lchip, table, field, &val_32, &netrx_cal, dp_id, i);

        cmd = DRV_IOW(table, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, entry_id, cmd, &netrx_cal));
    }

    /*WalkerEnd*/
    val_32 = walk_end;
    if(is_back_cal)
        DRV_IOW_FIELD_NZ(lchip, NetRxCalCtl_t, NetRxCalCtl_cfgCal1WalkEndPtr_f,
            &val_32, &cal_ctl, dp_id, 0);
    else
        DRV_IOW_FIELD_NZ(lchip, NetRxCalCtl_t, NetRxCalCtl_cfgCal0WalkEndPtr_f,
            &val_32, &cal_ctl, dp_id, 0);
    entry_id = DRV_INS(dp_id, 0);
    cmd = DRV_IOW(NetRxCalCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, entry_id, cmd, &cal_ctl));

    /*BankSel*/
    cmd = DRV_IOR(NetRxCalCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, entry_id, cmd, &cal_ctl));
    val_32 = 1;
    DRV_IOW_FIELD_NZ(lchip, NetRxCalCtl_t, NetRxCalCtl_cfgCalUsedEn_f,
            &val_32, &cal_ctl, dp_id, 0);
    val_32 = is_back_cal;
    DRV_IOW_FIELD_NZ(lchip, NetRxCalCtl_t, NetRxCalCtl_cfgCalSel_f,
            &val_32, &cal_ctl, dp_id, 0);
    cmd = DRV_IOW(NetRxCalCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, entry_id, cmd, &cal_ctl));

    return CTC_E_NONE;
}

void
print_cal_result(uint16* cal, uint16 walk_end)
{
    uint32 i;
    printf("\nprint_cal_result: walk_end %u\n", walk_end);
    for(i = 0; i <= walk_end; i++)
    {
        printf("%u ", cal[i]);
    }
    printf("\n");
}

/*Epe, NetRx, BufRetrv share one same calendar algorithm*/
int32 
_sys_tmg_datapath_set_general_calendar(uint8 lchip, uint8 dp_id)
{
    int32   ret      = CTC_E_NONE;
    uint16* cal      = NULL;
    uint16  walk_end = 0;
    sys_cal_info_collect_t* cal_info = NULL;

    cal = (uint16*)mem_malloc(MEM_DMPS_MODULE, SYS_TMG_MAX_CAL_LEN * sizeof(uint16));
    CTC_ERROR_GOTO((NULL == cal) ? CTC_E_NO_MEMORY : CTC_E_NONE, ret, RELEASE_PTR_RETURN_1);
    sal_memset(cal, 0, SYS_TMG_MAX_CAL_LEN * sizeof(uint16));

    cal_info = (sys_cal_info_collect_t*)mem_malloc(MEM_DMPS_MODULE, SYS_TMG_MAC_CLIENT_NUM_PER_DP * sizeof(sys_cal_info_collect_t));
    CTC_ERROR_GOTO((NULL == cal_info) ? CTC_E_NO_MEMORY : CTC_E_NONE, ret, RELEASE_PTR_RETURN_2);

    CTC_ERROR_GOTO(_sys_tmg_calendar_speed_info_collect(lchip, cal_info, dp_id, SYS_TMG_TXQM_NUM_PER_DP, SYS_DMPS_EPE_CAL), 
        ret, RELEASE_PTR_RETURN_3);

    /*1. calendar with cpumac*/
    CTC_ERROR_GOTO(_sys_tmg_datapath_calculate_general_calendar_parser(lchip, dp_id, cal, &walk_end, cal_info), 
        ret, RELEASE_PTR_RETURN_3);
    /*print_cal_result(cal, walk_end);*/

    if(SYS_TMG_MAX_CAL_LEN > walk_end)
    {
        /*1.1 EPE consider cpumac*/
        CTC_ERROR_GOTO(_sys_tmg_datapath_epe_cal_cfg(lchip, dp_id, cal, walk_end), ret, RELEASE_PTR_RETURN_3);

        /*1.2 BR consider cpumac*/
        CTC_ERROR_GOTO(_sys_tmg_datapath_br_cal_cfg(lchip, dp_id, cal, walk_end), ret, RELEASE_PTR_RETURN_3);
    }

    /*2. calendar without cpumac*/
    CTC_ERROR_GOTO(_sys_tmg_calendar_speed_info_collect(lchip, cal_info, dp_id, SYS_TMG_TXQM_NUM_PER_DP, SYS_DMPS_NETRX_CAL), 
        ret, RELEASE_PTR_RETURN_3);

    CTC_ERROR_GOTO(_sys_tmg_datapath_calculate_general_calendar_parser(lchip, dp_id, cal, &walk_end, cal_info), 
        ret, RELEASE_PTR_RETURN_3);
    /*print_cal_result(cal, walk_end);*/

    if(SYS_TMG_MAX_CAL_LEN > walk_end)
    {
        /*2.1 NetRx no cpumac*/
        CTC_ERROR_GOTO(_sys_tmg_datapath_netrx_cal_cfg(lchip, dp_id, cal, walk_end), ret, RELEASE_PTR_RETURN_3);
    }
    
RELEASE_PTR_RETURN_3:
    mem_free(cal_info);
RELEASE_PTR_RETURN_2:
    mem_free(cal);
RELEASE_PTR_RETURN_1:
    return ret;
}

/* check datapath_cfg.txt param validity */
STATIC int32
_sys_tmg_datapath_cfg_param_check(uint8 lchip, ctc_datapath_global_cfg_t* p_datapath_cfg)
{
    uint8 dual_cnt = 0;
    uint8 quad_cnt = 0;
    uint8 dual_flag = FALSE;
    uint8 quad_flag = FALSE;
    uint8 lane_num  = 0;
    uint16 logic_serdes_id;
    uint16 physic_serdes;
    uint16 lane;
    uint8 physic_serdes_used[CTC_DATAPATH_SERDES_NUM] = {0};
    ctc_datapath_serdes_prop_t *p_serdes = p_datapath_cfg->serdes;

    if((0 != p_datapath_cfg->flexe_client_num[0]) || (0 != p_datapath_cfg->flexe_client_num[1]))
    {
        SYS_DATAPATH_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, " Error 18: FlexE not support!\n");
        return CTC_E_NOT_SUPPORT;
    }
    /*printf("idx grp mod dyn lan lsd psd\n");
    for(logic_serdes_id = 0; logic_serdes_id < 84; logic_serdes_id++)
    {
        printf("%u   %u   %u   %u   %u   %u   %u  \n", logic_serdes_id, p_datapath_cfg->serdes[logic_serdes_id].group, p_datapath_cfg->serdes[logic_serdes_id].mode, p_datapath_cfg->serdes[logic_serdes_id].is_dynamic, p_datapath_cfg->serdes[logic_serdes_id].logical_lane_id, p_datapath_cfg->serdes[logic_serdes_id].logical_serdes_id, p_datapath_cfg->serdes[logic_serdes_id].physical_serdes_id);
    }*/
    for(logic_serdes_id = 0; logic_serdes_id < MCHIP_CAP(SYS_CAP_DMPS_SERDES_NUM_PER_SLICE); logic_serdes_id++)
    {
        SYS_TMG_GET_LANE_NUM_BY_MODE(p_serdes[logic_serdes_id].mode, lane_num);

        if(SYS_TMG_IS_MODE_NONE(p_serdes[logic_serdes_id].mode))
        {
            p_serdes[logic_serdes_id].mode = CTC_CHIP_SERDES_NONE_MODE;
        }

        /*multi-lane mode check*/
        switch(lane_num)
        {
            case 2:
                if(0 != quad_cnt)
                {
                    SYS_DATAPATH_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, " Error 11: Serdes logic lane %u mode %u dual %u quad %u!\n",
                        logic_serdes_id, p_serdes[logic_serdes_id].mode, dual_cnt, quad_cnt);
                    return CTC_E_INVALID_CONFIG;
                }
                /*invalid condition: current lane is 0 in a multi-lane series (!dual_flag), but no lane count before*/
                if((0 != dual_cnt) && (!dual_flag))
                {
                    SYS_DATAPATH_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, " Error 1: serdes logic lane %u mode %u!\n",
                        logic_serdes_id, p_serdes[logic_serdes_id].mode);
                    return CTC_E_INVALID_CONFIG;
                }
                /*invalid condition: current lane is 0 in a multi-lane series (0 == dual_cnt), but lane id is wrong*/
                if((0 == dual_cnt) && (0 != (logic_serdes_id % 2)))
                {
                    SYS_DATAPATH_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, " Error 2: Serdes logic lane %u mode %u!\n",
                        logic_serdes_id, p_serdes[logic_serdes_id].mode);
                    return CTC_E_INVALID_CONFIG;
                }

                dual_cnt++;
                dual_flag = TRUE;

                /*invalid condition: count of multi-lane exceeds max value*/
                if(2 < dual_cnt)
                {
                    SYS_DATAPATH_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, " Error 3: Serdes logic lane %u mode %u dual_cnt %u!\n",
                        logic_serdes_id, p_serdes[logic_serdes_id].mode, dual_cnt);
                    return CTC_E_INVALID_CONFIG;
                }
                /*if count of multi-lane reaches limit, set dual_flag to false for next multi-lane series*/
                else if(2 == dual_cnt)
                {
                    dual_flag = FALSE;
                    dual_cnt = 0;
                }
                break;
            case 4:
                if(0 != dual_cnt)
                {
                    SYS_DATAPATH_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, " Error 12: Serdes logic lane %u mode %u dual %u quad %u!\n",
                        logic_serdes_id, p_serdes[logic_serdes_id].mode, dual_cnt, quad_cnt);
                    return CTC_E_INVALID_CONFIG;
                }
                /*invalid condition: current lane is 0 in a multi-lane series (!dual_flag), but no lane count before*/
                if((0 != quad_cnt) && (!quad_flag))
                {
                    SYS_DATAPATH_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, " Error 4: serdes logic lane %u mode %u!\n",
                        logic_serdes_id, p_serdes[logic_serdes_id].mode);
                    return CTC_E_INVALID_CONFIG;
                }
                /*invalid condition: current lane is 0 in a multi-lane series (0 == dual_cnt), but lane id is wrong*/
                if((0 == quad_cnt) && (0 != (logic_serdes_id % 4)))
                {
                    SYS_DATAPATH_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, " Error 5: Serdes logic lane %u mode %u!\n",
                        logic_serdes_id, p_serdes[logic_serdes_id].mode);
                    return CTC_E_INVALID_CONFIG;
                }

                quad_cnt++;
                quad_flag = TRUE;

                /*invalid condition: count of multi-lane exceeds max value*/
                if(4 < quad_cnt)
                {
                    SYS_DATAPATH_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, " Error 6: Serdes logic lane %u mode %u quad_cnt %u!\n",
                        logic_serdes_id, p_serdes[logic_serdes_id].mode, quad_cnt);
                    return CTC_E_INVALID_CONFIG;
                }
                /*if count of multi-lane reaches limit, set dual_flag to false for next multi-lane series*/
                else if(4 == quad_cnt)
                {
                    quad_flag = FALSE;
                    quad_cnt = 0;
                }
                break;
            case 1:
            default:
                if((0 != dual_cnt) || (0 != quad_cnt))
                {
                    SYS_DATAPATH_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, " Error 14: Serdes logic lane %u mode %u dual %u quad %u!\n",
                        logic_serdes_id, p_serdes[logic_serdes_id].mode, dual_cnt, quad_cnt);
                    return CTC_E_INVALID_CONFIG;
                }
                dual_cnt = 0;
                quad_cnt = 0;
                break;
        }

        /*serdes map valid check*/
        physic_serdes = p_serdes[logic_serdes_id].physical_serdes_id;
        lane = SYS_TMG_GET_INNER_LANE_BY_SERDES(physic_serdes);
        switch(lane)
        {
            case 0:
            case 2:
                if(0 != (SYS_TMG_GET_INNER_LANE_BY_SERDES(logic_serdes_id) % 2))
                {
                    SYS_DATAPATH_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, " Serdes map error! serdes id %u, logic id %u\n",
                        physic_serdes, logic_serdes_id);
                    return CTC_E_INVALID_CONFIG;
                }
                break;
            case 1:
            case 3:
            default:
                if(lane != SYS_TMG_GET_INNER_LANE_BY_SERDES(logic_serdes_id))
                {
                    SYS_DATAPATH_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, " Serdes map error! serdes id %u, logic id %u\n",
                        physic_serdes, logic_serdes_id);
                    return CTC_E_INVALID_CONFIG;
                }
                break;
        }
        if(MCHIP_CAP(SYS_CAP_DMPS_SERDES_NUM_PER_SLICE) > physic_serdes)
        {
            if(SYS_TMG_GET_HSS_ID_BY_SERDES(logic_serdes_id) != SYS_TMG_GET_HSS_ID_BY_SERDES(physic_serdes))
            {
                SYS_DATAPATH_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, " Serdes map out of bound! serdes id %u, logic id %u\n",
                    physic_serdes, logic_serdes_id);
                return CTC_E_INVALID_CONFIG;
            }
            if(0 != physic_serdes_used[physic_serdes])
            {
                SYS_DATAPATH_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, " Serdes map duplicate! serdes id %u, logic id %u\n",
                    physic_serdes, logic_serdes_id);
                return CTC_E_EXIST;
            }
            physic_serdes_used[physic_serdes] = 1;
        }
    }

    /*CPUMAC As Network check. when cpumac_dp0_network_en not equal cpumac_dp1_network_en, dno't support 40G/100G */
    if((p_datapath_cfg->cpumac_dp0_network_en != p_datapath_cfg->cpumac_dp1_network_en))
    {
        for(logic_serdes_id = SYS_TMG_MAX_SERDES_NUM_NW; logic_serdes_id < SYS_TMG_MAX_SERDES_NUM; logic_serdes_id ++)
        {
            if((CTC_CHIP_SERDES_XLG_MODE == p_serdes[logic_serdes_id].mode) || (CTC_CHIP_SERDES_CG_MODE == p_serdes[logic_serdes_id].mode))
            {
                break;
            }
        }
        if(logic_serdes_id < SYS_TMG_MAX_SERDES_NUM)
        {
            SYS_DATAPATH_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, " SerDes 80 - 83 cannot be 100GR4 or 40GCR4 mode!\n");
            return CTC_E_INVALID_CONFIG;
        }
    }

    return CTC_E_NONE;
}

#if (SDB_MEM_MODEL != SDB_MODE)
STATIC int32
_sys_tmg_datapath_init_core_pll(uint8 lchip, uint16 core_pll)
{
#ifndef EMULATION_ENV
    PllCoreCfg_m core_cfg;
    PllLockMon_m core_mon;
    PllTsCfg_m   ts_cfg;
    PllTodCfg_m  tod_cfg;
    SupMiscCfg_m sm_cfg;
    uint32 cmd = 0;
    uint32 value = 0;
    uint32 islock = 0;

    if (1 == SDK_WORK_PLATFORM)
    {
        return DRV_E_NONE;
    }

    sal_memset(&core_cfg, 0, sizeof(PllCoreCfg_m));
    sal_memset(&core_mon, 0, sizeof(PllLockMon_m));

    /*reset core pll*/
    cmd = DRV_IOR(PllCoreCfg_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &core_cfg));
    value = 0;
    DRV_IOW_FIELD(lchip, PllCoreCfg_t, PllCoreCfg_cfgPllEn_f, &value, &core_cfg);
    cmd = DRV_IOW(PllCoreCfg_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &core_cfg));

    cmd = DRV_IOR(PllCoreCfg_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &core_cfg));

    if(core_pll == 925)
    {
        value = 2;
        DRV_IOW_FIELD(lchip, PllCoreCfg_t, PllCoreCfg_cfgPllRefDiv_f, &value, &core_cfg);
        value = 111;
        DRV_IOW_FIELD(lchip, PllCoreCfg_t, PllCoreCfg_cfgPllFbDiv_f, &value, &core_cfg);
        value = 1;
        DRV_IOW_FIELD(lchip, PllCoreCfg_t, PllCoreCfg_cfgPllFoutPostDivEn_f, &value, &core_cfg);
        value = 3;
        DRV_IOW_FIELD(lchip, PllCoreCfg_t, PllCoreCfg_cfgPllPostDiv1_f, &value, &core_cfg);
        value = 1;
        DRV_IOW_FIELD(lchip, PllCoreCfg_t, PllCoreCfg_cfgPllPostDiv2_f, &value, &core_cfg);
    }
    else if(core_pll == 650)
    {
        value = 1;
        DRV_IOW_FIELD(lchip, PllCoreCfg_t, PllCoreCfg_cfgPllRefDiv_f, &value, &core_cfg);
        value = 52;
        DRV_IOW_FIELD(lchip, PllCoreCfg_t, PllCoreCfg_cfgPllFbDiv_f, &value, &core_cfg);
        value = 1;
        DRV_IOW_FIELD(lchip, PllCoreCfg_t, PllCoreCfg_cfgPllFoutPostDivEn_f, &value, &core_cfg);
        value = 4;
        DRV_IOW_FIELD(lchip, PllCoreCfg_t, PllCoreCfg_cfgPllPostDiv1_f, &value, &core_cfg);
        value = 1;
        DRV_IOW_FIELD(lchip, PllCoreCfg_t, PllCoreCfg_cfgPllPostDiv2_f, &value, &core_cfg);
    }
    else
    {
        return CTC_E_INVALID_PARAM;
    }

    value = 0;
    DRV_IOW_FIELD(lchip, PllCoreCfg_t, PllCoreCfg_cfgPllDacEn_f, &value, &core_cfg);
    value = 0;
    DRV_IOW_FIELD(lchip, PllCoreCfg_t, PllCoreCfg_cfgPllDsmEn_f, &value, &core_cfg);
    value = 0;
    DRV_IOW_FIELD(lchip, PllCoreCfg_t, PllCoreCfg_cfgPllFout2XEn_f, &value, &core_cfg);
    value = 0;
    DRV_IOW_FIELD(lchip, PllCoreCfg_t, PllCoreCfg_cfgPllFout4PhaseEn_f, &value, &core_cfg);
    value = 0;
    DRV_IOW_FIELD(lchip, PllCoreCfg_t, PllCoreCfg_cfgPllOffserCalEn_f, &value, &core_cfg);
    value = 1;
    DRV_IOW_FIELD(lchip, PllCoreCfg_t, PllCoreCfg_cfgPllOffsetCalByp_f, &value, &core_cfg);
    value = 2;
    DRV_IOW_FIELD(lchip, PllCoreCfg_t, PllCoreCfg_cfgPllOffsetCalCnt_f, &value, &core_cfg);
    value = 0;
    DRV_IOW_FIELD(lchip, PllCoreCfg_t, PllCoreCfg_cfgPllOffsetCalIn_f, &value, &core_cfg);
    value = 0;
    DRV_IOW_FIELD(lchip, PllCoreCfg_t, PllCoreCfg_cfgPllOffsetFastCal_f, &value, &core_cfg);
    value = 0;
    DRV_IOW_FIELD(lchip, PllCoreCfg_t, PllCoreCfg_cfgPllBypass_f, &value, &core_cfg);


    cmd = DRV_IOW(PllCoreCfg_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &core_cfg));

    sal_task_sleep(1);

    /*release reset core pll powerdown*/
    cmd = DRV_IOR(PllCoreCfg_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &core_cfg));
    value = 1;
    DRV_IOW_FIELD(lchip, PllCoreCfg_t, PllCoreCfg_cfgPllEn_f, &value, &core_cfg);
    cmd = DRV_IOW(PllCoreCfg_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &core_cfg));

    sal_task_sleep(100);

    /*check pll lock*/
    cmd = DRV_IOR(PllLockMon_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &core_mon));
    if(0 == SDK_WORK_PLATFORM)
    {
        DRV_IOR_FIELD(lchip, PllLockMon_t, PllLockMon_monPllCoreLock_f, &islock, &core_mon);
        if(0 == islock)
        {
            SYS_DATAPATH_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, " [DATAPATH] pll cannot lock \n");
            return CTC_E_HW_NOT_LOCK;
        }
    }

    /*SupMiscCfg.cfgPllCoreRefClkByp write 0*/
    cmd = DRV_IOR(SupMiscCfg_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &sm_cfg));
    value = 0;
    DRV_IOW_FIELD(lchip, SupMiscCfg_t, SupMiscCfg_cfgPllCoreRefClkByp_f, &value, &sm_cfg);
    cmd = DRV_IOW(SupMiscCfg_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &sm_cfg));

    /*Ts Clock Configuration*/
    cmd = DRV_IOR(PllTsCfg_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ts_cfg));
    value = 1;
    DRV_IOW_FIELD(lchip, PllTsCfg_t, PllTsCfg_cfgPllEn_f, &value, &ts_cfg);
    cmd = DRV_IOW(PllTsCfg_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &ts_cfg));

    /*TOD Clock Configuration*/
    cmd = DRV_IOR(PllTodCfg_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &tod_cfg));
    value = 1;
    DRV_IOW_FIELD(lchip, PllTodCfg_t, PllTodCfg_cfgPllEn_f, &value, &tod_cfg);
    cmd = DRV_IOW(PllTodCfg_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &tod_cfg));
#endif

    return CTC_E_NONE;
}

///TODO: need to be changed
STATIC int32
_sys_tmg_datapath_init_suprst(uint8 lchip)
{
    uint32               cmd   = 0;
    uint32               value = 0;
    uint32               index = 0;
    uint8                i     = 0;
    uint32               value_arr[2];
    uint32               sup_rst[2];
    uint32 write_st[SYS_MAC_MAX_STRUCT_WORD] = {0};

    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s\n", __FUNCTION__);

    /*clear demuxLogErrValid*/
    cmd = DRV_IOR(DecodeMiscCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, write_st));
    value = 1;
    DRV_IOW_FIELD(lchip, DecodeMiscCtl_t, DecodeMiscCtl_cfgDemuxInitEn_f, &value, write_st);
    cmd = DRV_IOW(DecodeMiscCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, write_st));
    value = 0;
    DRV_IOW_FIELD(lchip, DecodeMiscCtl_t, DecodeMiscCtl_cfgDemuxInitEn_f, &value, write_st);
    cmd = DRV_IOW(DecodeMiscCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, write_st));

    sal_task_sleep(3000);

    /*new add*/
    cmd = DRV_IOR(PcieResetCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, write_st));
    write_st[0] = 0;    
    cmd = DRV_IOW(PcieResetCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, write_st));

    /*do SupResetCtl reset*/
    sup_rst[0] = 0xffffffff;
    sup_rst[1] = 0xffffffff;
    SetSupResetCtl(V,cfgRstEcpuIntf_f, sup_rst, 0);/* reset ECPU in sys_usw_eunit_init */
    SetSupResetCtl(V,cfgRstScpuIntf_f, sup_rst, 0);/* reset SCPU in sys_usw_eunit_init */
    cmd = DRV_IOW(SupResetCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &sup_rst));
    DMPS_DUMP_PRINT("write address 0x000510a8 0xffffffff\n");
    DMPS_DUMP_PRINT("write address 0x000510ac 0x00003fff\n");
    sal_task_sleep(1);
    sup_rst[0] = 0;
    sup_rst[1] = 0;
    cmd = DRV_IOW(SupResetCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &sup_rst));
    DMPS_DUMP_PRINT("write address 0x000510a8 0x0\n");
    DMPS_DUMP_PRINT("write address 0x000510ac 0x0\n");

    cmd = DRV_IOR(SupResetCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &sup_rst));
    if (!GetSupResetCtl(V, resetDmaCtl_f, &sup_rst))
    {
        for (index=0;index <MCHIP_CAP(SYS_CAP_DMA_MAX_CHAN_ID); index++)
        {
            cmd = DRV_IOR(DmaStaticInfo_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, write_st));
            SetDmaStaticInfo(V, chanEn_f, write_st, 0);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, write_st));
            DRV_IOCTL(lchip, index, cmd, write_st);
        }
        sal_task_sleep(2);
    }

    /* PcieReg.txt */
    cmd = DRV_IOR(SupRegCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, write_st));
    value = 1;
    DRV_IOW_FIELD(lchip, SupRegCtl_t, SupRegCtl_regReqCrossEn_f, &value, write_st);
    cmd = DRV_IOW(SupRegCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, write_st));

    /*Open clock enable*/
    cmd = DRV_IOR(SupEnClk_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, write_st));
    value = 0xffff;
    DRV_IOW_FIELD(lchip, SupEnClk_t, SupEnClk_cfgEnClkVec_f, &value, write_st);
    cmd = DRV_IOW(SupEnClk_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, write_st));

#ifndef EMULATION_ENV
    cmd = DRV_IOR(SupDskCfg_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, write_st));
    value = 0;
    DRV_IOW_FIELD(lchip, SupDskCfg_t, SupDskCfg_cfgResetClkHssRegAccDiv_f,  &value, write_st);
    DRV_IOW_FIELD(lchip, SupDskCfg_t, SupDskCfg_cfgResetClkLedDiv_f,        &value, write_st);
    DRV_IOW_FIELD(lchip, SupDskCfg_t, SupDskCfg_cfgResetClkMdioADiv_f,      &value, write_st);
    DRV_IOW_FIELD(lchip, SupDskCfg_t, SupDskCfg_cfgResetClkMdioBDiv_f,      &value, write_st);
    DRV_IOW_FIELD(lchip, SupDskCfg_t, SupDskCfg_cfgResetClkMdioCDiv_f,      &value, write_st);
    DRV_IOW_FIELD(lchip, SupDskCfg_t, SupDskCfg_cfgResetClkMdioDDiv_f,      &value, write_st);
    DRV_IOW_FIELD(lchip, SupDskCfg_t, SupDskCfg_cfgResetClkMiscADiv_f,      &value, write_st);
    DRV_IOW_FIELD(lchip, SupDskCfg_t, SupDskCfg_cfgResetClkTodDiv_f,        &value, write_st);   
    DRV_IOW_FIELD(lchip, SupDskCfg_t, SupDskCfg_cfgResetClkSensorDiv_f,        &value, write_st);
    cmd = DRV_IOW(SupDskCfg_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, write_st));
#endif
    cmd = DRV_IOR(RefDivOamTokenUpd_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, write_st));
    value = 0;
    DRV_IOW_FIELD(lchip, RefDivOamTokenUpd_t, RefDivOamTokenUpd_cfgResetDivOamTokenUpdPulse_f,  &value, write_st);
    cmd = DRV_IOW(RefDivOamTokenUpd_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, write_st));

    /*Release Reset*/
    for (i = 0; i < 2; i++)
    {
        cmd = DRV_IOR(CtcNetCtlReset_t, DRV_ENTRY_FLAG);
        index = DRV_INS(i, 0);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, write_st));
        value = 0;
        DRV_IOW_FIELD_NZ(lchip, CtcNetCtlReset_t, CtcNetCtlReset_resetCoreEpeSchedule_f, &value, write_st, i, 0);
        DRV_IOW_FIELD_NZ(lchip, CtcNetCtlReset_t, CtcNetCtlReset_resetCoreNetRx_f,       &value, write_st, i, 0);
        DRV_IOW_FIELD_NZ(lchip, CtcNetCtlReset_t, CtcNetCtlReset_resetCoreNetTx_f,       &value, write_st, i, 0);
        cmd = DRV_IOW(CtcNetCtlReset_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, write_st));
    }

    /*CtcIpeRxCtlReset*/
    cmd = DRV_IOR(CtcIpeRxCtlReset_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, write_st));
    value = 0;
    DRV_IOW_FIELD(lchip, CtcIpeRxCtlReset_t, CtcIpeRxCtlReset_resetCoreEfd_f,                &value, write_st);
    DRV_IOW_FIELD(lchip, CtcIpeRxCtlReset_t, CtcIpeRxCtlReset_resetCoreIpeHdrAdj_f,          &value, write_st);
    DRV_IOW_FIELD(lchip, CtcIpeRxCtlReset_t, CtcIpeRxCtlReset_resetCoreIpeIntfMap_f,         &value, write_st);
    DRV_IOW_FIELD(lchip, CtcIpeRxCtlReset_t, CtcIpeRxCtlReset_resetCoreIpeLkupMgrTop_f,      &value, write_st);
    DRV_IOW_FIELD(lchip, CtcIpeRxCtlReset_t, CtcIpeRxCtlReset_resetCoreIpePktProc_f,         &value, write_st);
    DRV_IOW_FIELD(lchip, CtcIpeRxCtlReset_t, CtcIpeRxCtlReset_resetCoreOamHash_f,            &value, write_st);
    DRV_IOW_FIELD(lchip, CtcIpeRxCtlReset_t, CtcIpeRxCtlReset_resetCoreParser0Ipe_f,         &value, write_st);
    DRV_IOW_FIELD(lchip, CtcIpeRxCtlReset_t, CtcIpeRxCtlReset_resetCoreParser1Ipe_f,         &value, write_st);
    DRV_IOW_FIELD(lchip, CtcIpeRxCtlReset_t, CtcIpeRxCtlReset_resetCoreSclEngine_f,          &value, write_st);
    DRV_IOW_FIELD(lchip, CtcIpeRxCtlReset_t, CtcIpeRxCtlReset_resetCoreSvcPolicing_f,        &value, write_st);
    DRV_IOW_FIELD(lchip, CtcIpeRxCtlReset_t, CtcIpeRxCtlReset_resetCoreIpeAcl_f,             &value, write_st);
    cmd = DRV_IOW(CtcIpeRxCtlReset_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, write_st));

    /*CtcBsrCtlReset*/
    cmd = DRV_IOR(CtcBsrCtlReset_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, write_st));
    value = 0;
    DRV_IOW_FIELD(lchip, CtcBsrCtlReset_t, CtcBsrCtlReset_resetCoreBufRetrvShare_f,     &value, write_st);
    DRV_IOW_FIELD(lchip, CtcBsrCtlReset_t, CtcBsrCtlReset_resetCoreBufRetrvSlice0Dp0_f, &value, write_st);
    DRV_IOW_FIELD(lchip, CtcBsrCtlReset_t, CtcBsrCtlReset_resetCoreBufRetrvSlice0Dp1_f, &value, write_st);
    DRV_IOW_FIELD(lchip, CtcBsrCtlReset_t, CtcBsrCtlReset_resetCoreBufStore_f,          &value, write_st);
    DRV_IOW_FIELD(lchip, CtcBsrCtlReset_t, CtcBsrCtlReset_resetCoreMetFifoProc0_f,      &value, write_st);
    DRV_IOW_FIELD(lchip, CtcBsrCtlReset_t, CtcBsrCtlReset_resetCoreMetFifoShare_f,      &value, write_st);
    DRV_IOW_FIELD(lchip, CtcBsrCtlReset_t, CtcBsrCtlReset_resetCoreSupSensor_f,         &value, write_st);
    cmd = DRV_IOW(CtcBsrCtlReset_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, write_st));

    /*CtcMacCtlReset*/
    /*CtcHsCtlReset*/
    /*CtcPcsCtlCfg*/
    for (i = 0; i < SYS_TMG_TXQM_NUM_PER_DP*SYS_TMG_DP_NUM; i++)
    {
        #if 0
        index = DRV_INS(i, 0);
        
        cmd = DRV_IOR(CtcHsCtlReset_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, write_st));
        value = 0;
        DRV_IOW_FIELD_NZ(lchip, CtcHsCtlReset_t, CtcHsCtlReset_resetCoreCtcMac_f,     &value, write_st, i, 0);
        DRV_IOW_FIELD_NZ(lchip, CtcHsCtlReset_t, CtcHsCtlReset_resetCoreCtcPcs_f,     &value, write_st, i, 0);
        DRV_IOW_FIELD_NZ(lchip, CtcHsCtlReset_t, CtcHsCtlReset_resetCoreMcu_f,        &value, write_st, i, 0);
        DRV_IOW_FIELD_NZ(lchip, CtcHsCtlReset_t, CtcHsCtlReset_resetCoreMcuIntf_f,    &value, write_st, i, 0);
        cmd = DRV_IOW(CtcHsCtlReset_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, write_st));
        
        cmd = DRV_IOR(CtcMacCtlReset_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, write_st));
        value = 0;
        DRV_IOW_FIELD_NZ(lchip, CtcMacCtlReset_t, CtcMacCtlReset_resetCoreQuadSgmac0_f,     &value, write_st, i, 0);
        DRV_IOW_FIELD_NZ(lchip, CtcMacCtlReset_t, CtcMacCtlReset_resetCoreQuadSgmac1_f,     &value, write_st, i, 0);
        DRV_IOW_FIELD_NZ(lchip, CtcMacCtlReset_t, CtcMacCtlReset_resetCoreQuadSgmacReg0_f,  &value, write_st, i, 0);
        DRV_IOW_FIELD_NZ(lchip, CtcMacCtlReset_t, CtcMacCtlReset_resetCoreQuadSgmacReg1_f,  &value, write_st, i, 0);
        cmd = DRV_IOW(CtcMacCtlReset_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, write_st));
        
        cmd = DRV_IOR(CtcPcsCtlCfg_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, write_st));
        value = 0;
        DRV_IOW_FIELD_NZ(lchip, CtcPcsCtlCfg_t, CtcPcsCtlCfg_resetCoreCgPcs0_f,                &value, write_st, i, 0);
        DRV_IOW_FIELD_NZ(lchip, CtcPcsCtlCfg_t, CtcPcsCtlCfg_resetCoreCgPcs1_f,                &value, write_st, i, 0);
        DRV_IOW_FIELD_NZ(lchip, CtcPcsCtlCfg_t, CtcPcsCtlCfg_resetCoreHss32GUnitWrapper0_f,    &value, write_st, i, 0);
        DRV_IOW_FIELD_NZ(lchip, CtcPcsCtlCfg_t, CtcPcsCtlCfg_resetCoreHss32GUnitWrapper1_f,    &value, write_st, i, 0);
        DRV_IOW_FIELD_NZ(lchip, CtcPcsCtlCfg_t, CtcPcsCtlCfg_resetCoreHss32GUnitWrapperReg0_f, &value, write_st, i, 0);
        DRV_IOW_FIELD_NZ(lchip, CtcPcsCtlCfg_t, CtcPcsCtlCfg_resetCoreHss32GUnitWrapperReg1_f, &value, write_st, i, 0);
        DRV_IOW_FIELD_NZ(lchip, CtcPcsCtlCfg_t, CtcPcsCtlCfg_resetCoreMii0_f,                  &value, write_st, i, 0);
        DRV_IOW_FIELD_NZ(lchip, CtcPcsCtlCfg_t, CtcPcsCtlCfg_resetCoreMii1_f,                  &value, write_st, i, 0);
        DRV_IOW_FIELD_NZ(lchip, CtcPcsCtlCfg_t, CtcPcsCtlCfg_resetCoreMii2_f,                  &value, write_st, i, 0);
        DRV_IOW_FIELD_NZ(lchip, CtcPcsCtlCfg_t, CtcPcsCtlCfg_resetCoreMii3_f,                  &value, write_st, i, 0);
        DRV_IOW_FIELD_NZ(lchip, CtcPcsCtlCfg_t, CtcPcsCtlCfg_resetCoreMii4_f,                  &value, write_st, i, 0);
        DRV_IOW_FIELD_NZ(lchip, CtcPcsCtlCfg_t, CtcPcsCtlCfg_resetCoreMii5_f,                  &value, write_st, i, 0);
        DRV_IOW_FIELD_NZ(lchip, CtcPcsCtlCfg_t, CtcPcsCtlCfg_resetCoreMii6_f,                  &value, write_st, i, 0);
        DRV_IOW_FIELD_NZ(lchip, CtcPcsCtlCfg_t, CtcPcsCtlCfg_resetCoreMii7_f,                  &value, write_st, i, 0);
        DRV_IOW_FIELD_NZ(lchip, CtcPcsCtlCfg_t, CtcPcsCtlCfg_resetCorePcs0_f,                  &value, write_st, i, 0);
        DRV_IOW_FIELD_NZ(lchip, CtcPcsCtlCfg_t, CtcPcsCtlCfg_resetCorePcs1_f,                  &value, write_st, i, 0);
        DRV_IOW_FIELD_NZ(lchip, CtcPcsCtlCfg_t, CtcPcsCtlCfg_resetCorePcs2_f,                  &value, write_st, i, 0);
        DRV_IOW_FIELD_NZ(lchip, CtcPcsCtlCfg_t, CtcPcsCtlCfg_resetCorePcs3_f,                  &value, write_st, i, 0);
        DRV_IOW_FIELD_NZ(lchip, CtcPcsCtlCfg_t, CtcPcsCtlCfg_resetCorePcs4_f,                  &value, write_st, i, 0);
        DRV_IOW_FIELD_NZ(lchip, CtcPcsCtlCfg_t, CtcPcsCtlCfg_resetCorePcs5_f,                  &value, write_st, i, 0);
        DRV_IOW_FIELD_NZ(lchip, CtcPcsCtlCfg_t, CtcPcsCtlCfg_resetCorePcs6_f,                  &value, write_st, i, 0);
        DRV_IOW_FIELD_NZ(lchip, CtcPcsCtlCfg_t, CtcPcsCtlCfg_resetCorePcs7_f,                  &value, write_st, i, 0);
        DRV_IOW_FIELD_NZ(lchip, CtcPcsCtlCfg_t, CtcPcsCtlCfg_resetCoreSharedFecReg0_f,         &value, write_st, i, 0);
        DRV_IOW_FIELD_NZ(lchip, CtcPcsCtlCfg_t, CtcPcsCtlCfg_resetCoreSharedFecReg1_f,         &value, write_st, i, 0);
        DRV_IOW_FIELD_NZ(lchip, CtcPcsCtlCfg_t, CtcPcsCtlCfg_resetCoreSharedMiiReg0_f,         &value, write_st, i, 0);
        DRV_IOW_FIELD_NZ(lchip, CtcPcsCtlCfg_t, CtcPcsCtlCfg_resetCoreSharedMiiReg1_f,         &value, write_st, i, 0);
        DRV_IOW_FIELD_NZ(lchip, CtcPcsCtlCfg_t, CtcPcsCtlCfg_resetCoreSharedPcsReg0_f,         &value, write_st, i, 0);
        DRV_IOW_FIELD_NZ(lchip, CtcPcsCtlCfg_t, CtcPcsCtlCfg_resetCoreSharedPcsReg1_f,         &value, write_st, i, 0);
        DRV_IOW_FIELD_NZ(lchip, CtcPcsCtlCfg_t, CtcPcsCtlCfg_resetCoreXlgPcs0_f,               &value, write_st, i, 0);
        DRV_IOW_FIELD_NZ(lchip, CtcPcsCtlCfg_t, CtcPcsCtlCfg_resetCoreXlgPcs1_f,               &value, write_st, i, 0);
        DRV_IOW_FIELD_NZ(lchip, CtcPcsCtlCfg_t, CtcPcsCtlCfg_resetCoreXlgPcs2_f,               &value, write_st, i, 0);
        DRV_IOW_FIELD_NZ(lchip, CtcPcsCtlCfg_t, CtcPcsCtlCfg_resetCoreXlgPcs3_f,               &value, write_st, i, 0);
        DRV_IOW_FIELD_NZ(lchip, CtcPcsCtlCfg_t, CtcPcsCtlCfg_resetSharedFec0_f,                &value, write_st, i, 0);
        DRV_IOW_FIELD_NZ(lchip, CtcPcsCtlCfg_t, CtcPcsCtlCfg_resetSharedFec1_f,                &value, write_st, i, 0);
        cmd = DRV_IOW(CtcPcsCtlCfg_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, write_st));
        #endif
    }  

    /*CtcMiscCtlReset*/
    cmd = DRV_IOR(CtcMiscCtlReset_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, write_st));
    value = 0;
    DRV_IOW_FIELD_NZ(lchip, CtcMiscCtlReset_t, CtcMiscCtlReset_resetCoreCpuMac_f,     &value, write_st, 0, 0);
    DRV_IOW_FIELD_NZ(lchip, CtcMiscCtlReset_t, CtcMiscCtlReset_resetCoreHMacEngine_f, &value, write_st, 0, 0);
    DRV_IOW_FIELD_NZ(lchip, CtcMiscCtlReset_t, CtcMiscCtlReset_resetCoreMcuIntf_f,    &value, write_st, 0, 0);
    DRV_IOW_FIELD_NZ(lchip, CtcMiscCtlReset_t, CtcMiscCtlReset_resetCoreMdio0_f,      &value, write_st, 0, 0);
    DRV_IOW_FIELD_NZ(lchip, CtcMiscCtlReset_t, CtcMiscCtlReset_resetCoreMdio1_f,      &value, write_st, 0, 0);
    DRV_IOW_FIELD_NZ(lchip, CtcMiscCtlReset_t, CtcMiscCtlReset_resetCoreOobFc_f,      &value, write_st, 0, 0);
    DRV_IOW_FIELD_NZ(lchip, CtcMiscCtlReset_t, CtcMiscCtlReset_resetMcu_f,            &value, write_st, 0, 0);
    cmd = DRV_IOW(CtcMiscCtlReset_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, write_st));

    /*CpuMacCtlResetCtl*/
    cmd = DRV_IOR(CpuMacCtlResetCtl_t, DRV_ENTRY_FLAG);
    index = DRV_INS(0, 0);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, write_st));
    value = 0;
    DRV_IOW_FIELD(lchip, CpuMacCtlResetCtl_t, CpuMacCtlResetCtl_resetCoreCgPcs_f,        	&value, write_st);
    DRV_IOW_FIELD(lchip, CpuMacCtlResetCtl_t, CpuMacCtlResetCtl_resetCoreLed_f,          	&value, write_st);
    DRV_IOW_FIELD(lchip, CpuMacCtlResetCtl_t, CpuMacCtlResetCtl_resetCoreMii0_f,         	&value, write_st);
    DRV_IOW_FIELD(lchip, CpuMacCtlResetCtl_t, CpuMacCtlResetCtl_resetCoreMii1_f,         	&value, write_st);
    DRV_IOW_FIELD(lchip, CpuMacCtlResetCtl_t, CpuMacCtlResetCtl_resetCoreMii2_f,         	&value, write_st);
    DRV_IOW_FIELD(lchip, CpuMacCtlResetCtl_t, CpuMacCtlResetCtl_resetCoreMii3_f,         	&value, write_st);
    DRV_IOW_FIELD(lchip, CpuMacCtlResetCtl_t, CpuMacCtlResetCtl_resetCorePcs0_f,         	&value, write_st);
    DRV_IOW_FIELD(lchip, CpuMacCtlResetCtl_t, CpuMacCtlResetCtl_resetCorePcs1_f,         	&value, write_st);
    DRV_IOW_FIELD(lchip, CpuMacCtlResetCtl_t, CpuMacCtlResetCtl_resetCorePcs2_f,         	&value, write_st);
    DRV_IOW_FIELD(lchip, CpuMacCtlResetCtl_t, CpuMacCtlResetCtl_resetCorePcs3_f,         	&value, write_st);
    DRV_IOW_FIELD(lchip, CpuMacCtlResetCtl_t, CpuMacCtlResetCtl_resetCoreQuadSgmac_f,       &value, write_st);
    DRV_IOW_FIELD(lchip, CpuMacCtlResetCtl_t, CpuMacCtlResetCtl_resetCoreQuadSgmacReg_f,    &value, write_st);
    DRV_IOW_FIELD(lchip, CpuMacCtlResetCtl_t, CpuMacCtlResetCtl_resetCoreSharedFecReg_f,    &value, write_st);
    DRV_IOW_FIELD(lchip, CpuMacCtlResetCtl_t, CpuMacCtlResetCtl_resetCoreSharedMiiReg_f,    &value, write_st);
    DRV_IOW_FIELD(lchip, CpuMacCtlResetCtl_t, CpuMacCtlResetCtl_resetCoreSharedPcsReg_f,    &value, write_st);
    DRV_IOW_FIELD(lchip, CpuMacCtlResetCtl_t, CpuMacCtlResetCtl_resetCoreXlgPcs0_f,         &value, write_st);
    DRV_IOW_FIELD(lchip, CpuMacCtlResetCtl_t, CpuMacCtlResetCtl_resetCoreXlgPcs1_f,         &value, write_st);
    DRV_IOW_FIELD(lchip, CpuMacCtlResetCtl_t, CpuMacCtlResetCtl_resetSharedFec_f,           &value, write_st);
    DRV_IOW_FIELD(lchip, CpuMacCtlResetCtl_t, CpuMacCtlResetCtl_resetHss32GUnitWrapperReg_f,&value, write_st);
    cmd = DRV_IOW(CpuMacCtlResetCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, write_st));

    /*CtcAdCtlReset*/
    cmd = DRV_IOR(CtcAdCtlReset_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, write_st));
    value = 0;
    DRV_IOW_FIELD(lchip, CtcAdCtlReset_t, CtcAdCtlReset_resetCoreDynamicAd_f,            &value, write_st);
    DRV_IOW_FIELD(lchip, CtcAdCtlReset_t, CtcAdCtlReset_resetCoreGemPortHash_f,          &value, write_st);
    DRV_IOW_FIELD(lchip, CtcAdCtlReset_t, CtcAdCtlReset_resetCoreMplsHash_f,             &value, write_st);
    DRV_IOW_FIELD(lchip, CtcAdCtlReset_t, CtcAdCtlReset_resetCoreDynamicMiscKey_f,       &value, write_st);
    DRV_IOW_FIELD(lchip, CtcAdCtlReset_t, CtcAdCtlReset_resetCoreEgrSclHash_f,           &value, write_st);
    DRV_IOW_FIELD(lchip, CtcAdCtlReset_t, CtcAdCtlReset_resetCoreUserIdHashSclKeyCmp_f,  &value, write_st);
    DRV_IOW_FIELD(lchip, CtcAdCtlReset_t, CtcAdCtlReset_resetCoreFibHashHost1_f,         &value, write_st);
    DRV_IOW_FIELD(lchip, CtcAdCtlReset_t, CtcAdCtlReset_resetCoreFlowHash_f,             &value, write_st);
    DRV_IOW_FIELD(lchip, CtcAdCtlReset_t, CtcAdCtlReset_resetCoreFibHashHost0_f,         &value, write_st);
    DRV_IOW_FIELD(lchip, CtcAdCtlReset_t, CtcAdCtlReset_resetCoreFibEngine_f,            &value, write_st);
    DRV_IOW_FIELD(lchip, CtcAdCtlReset_t, CtcAdCtlReset_resetCoreSupSensor_f,            &value, write_st);
    cmd = DRV_IOW(CtcAdCtlReset_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, write_st));

    /*CtcEditCtlReset*/
    cmd = DRV_IOR(CtcEditCtlReset_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, write_st));
    value = 0;
    DRV_IOW_FIELD(lchip, CtcEditCtlReset_t, CtcEditCtlReset_resetCoreDsAging_f,           &value, write_st);
    DRV_IOW_FIELD(lchip, CtcEditCtlReset_t, CtcEditCtlReset_resetCoreDynamicEdit_f,       &value, write_st);
    DRV_IOW_FIELD(lchip, CtcEditCtlReset_t, CtcEditCtlReset_resetCoreFibAcc_f,            &value, write_st);
    DRV_IOW_FIELD(lchip, CtcEditCtlReset_t, CtcEditCtlReset_resetCoreLpmTcam_f,           &value, write_st);
    DRV_IOW_FIELD(lchip, CtcEditCtlReset_t, CtcEditCtlReset_resetCoreOamEngine_f,         &value, write_st);
    cmd = DRV_IOW(CtcEditCtlReset_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, write_st));

    /*CtcIpeTxCtlReset*/
    cmd = DRV_IOR(CtcIpeTxCtlReset_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, write_st));
    value = 0;
    DRV_IOW_FIELD(lchip, CtcIpeTxCtlReset_t, CtcIpeTxCtlReset_resetCoreCoppIpe_f,     &value, write_st);
    DRV_IOW_FIELD(lchip, CtcIpeTxCtlReset_t, CtcIpeTxCtlReset_resetCoreEcmpDlb_f,     &value, write_st);
    DRV_IOW_FIELD(lchip, CtcIpeTxCtlReset_t, CtcIpeTxCtlReset_resetCoreFlowAcc_f,     &value, write_st);
    DRV_IOW_FIELD(lchip, CtcIpeTxCtlReset_t, CtcIpeTxCtlReset_resetCoreGlobalStats_f, &value, write_st);
    DRV_IOW_FIELD(lchip, CtcIpeTxCtlReset_t, CtcIpeTxCtlReset_resetCoreIpeFwd_f,      &value, write_st);
    DRV_IOW_FIELD(lchip, CtcIpeTxCtlReset_t, CtcIpeTxCtlReset_resetCoreIpfixHash_f,   &value, write_st);
    DRV_IOW_FIELD(lchip, CtcIpeTxCtlReset_t, CtcIpeTxCtlReset_resetCoreLinkAgg_f,     &value, write_st);
    DRV_IOW_FIELD(lchip, CtcIpeTxCtlReset_t, CtcIpeTxCtlReset_resetCorePolicingIpe_f, &value, write_st);
    DRV_IOW_FIELD(lchip, CtcIpeTxCtlReset_t, CtcIpeTxCtlReset_resetCoreStormCtl_f,    &value, write_st);
    cmd = DRV_IOW(CtcIpeTxCtlReset_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, write_st));

    /*CtcEpeCtlReset*/
    cmd = DRV_IOR(CtcEpeCtlReset_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, write_st));
    value = 0;
    DRV_IOW_FIELD(lchip, CtcEpeCtlReset_t, CtcEpeCtlReset_resetCoreCoppEpe_f,       &value, write_st);
    DRV_IOW_FIELD(lchip, CtcEpeCtlReset_t, CtcEpeCtlReset_resetCoreCoppGlbEpe_f,    &value, write_st);
    DRV_IOW_FIELD(lchip, CtcEpeCtlReset_t, CtcEpeCtlReset_resetCoreEgressAclTcam_f, &value, write_st);
    DRV_IOW_FIELD(lchip, CtcEpeCtlReset_t, CtcEpeCtlReset_resetCoreEpeAclOam_f,     &value, write_st);
    DRV_IOW_FIELD(lchip, CtcEpeCtlReset_t, CtcEpeCtlReset_resetCoreEpeHdrAdj_f,     &value, write_st);
    DRV_IOW_FIELD(lchip, CtcEpeCtlReset_t, CtcEpeCtlReset_resetCoreEpeHdrProc_f,    &value, write_st);
    DRV_IOW_FIELD(lchip, CtcEpeCtlReset_t, CtcEpeCtlReset_resetCoreEpeNextHop_f,    &value, write_st);
    DRV_IOW_FIELD(lchip, CtcEpeCtlReset_t, CtcEpeCtlReset_resetCoreLmStats_f,       &value, write_st);
    DRV_IOW_FIELD(lchip, CtcEpeCtlReset_t, CtcEpeCtlReset_resetCoreParserEpe_f,     &value, write_st);
    DRV_IOW_FIELD(lchip, CtcEpeCtlReset_t, CtcEpeCtlReset_resetCorePolicingEpe_f,   &value, write_st);
    DRV_IOW_FIELD(lchip, CtcEpeCtlReset_t, CtcEpeCtlReset_resetCoreEpePktRewrite_f, &value, write_st);
    DRV_IOW_FIELD(lchip, CtcEpeCtlReset_t, CtcEpeCtlReset_resetCoreEpeHdrEdit_f,    &value, write_st);
    DRV_IOW_FIELD(lchip, CtcEpeCtlReset_t, CtcEpeCtlReset_resetCoreTsEngine_f,      &value, write_st);
    DRV_IOW_FIELD(lchip, CtcEpeCtlReset_t, CtcEpeCtlReset_resetCoreSupSensor_f,     &value, write_st);
    cmd = DRV_IOW(CtcEpeCtlReset_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, write_st));

    /*CtcKeyCtlReset*/
    cmd = DRV_IOR(CtcKeyCtlReset_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, write_st));
    value = 0;
    DRV_IOW_FIELD(lchip, CtcKeyCtlReset_t, CtcKeyCtlReset_resetCoreDsAging_f,       &value, write_st);
    DRV_IOW_FIELD(lchip, CtcKeyCtlReset_t, CtcKeyCtlReset_resetCoreDynamicFibKey_f, &value, write_st);
    cmd = DRV_IOW(CtcKeyCtlReset_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, write_st));

    /*CtcQMgrCtlReset*/
    cmd = DRV_IOR(CtcQMgrCtlReset_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, write_st));
    value = 0;
    DRV_IOW_FIELD(lchip, CtcQMgrCtlReset_t, CtcQMgrCtlReset_resetCoreQMgrDeq_f,     &value, write_st);
    DRV_IOW_FIELD(lchip, CtcQMgrCtlReset_t, CtcQMgrCtlReset_resetCoreQMgrEnq_f,     &value, write_st);
    DRV_IOW_FIELD(lchip, CtcQMgrCtlReset_t, CtcQMgrCtlReset_resetCoreQMgrMsgStore_f,&value, write_st);
    cmd = DRV_IOW(CtcQMgrCtlReset_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, write_st));

    /*NetRxWrEnCtl*/
    cmd = DRV_IOR(NetRxWrEnCtl_t, DRV_ENTRY_FLAG);
    index = DRV_INS(0, 0);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, write_st));
    value_arr[0] = 0xffffffff;
    value_arr[1] = 0xff;
    DRV_IOW_FIELD_NZ(lchip, NetRxWrEnCtl_t, NetRxWrEnCtl_cfgWrEn0_f, value_arr, write_st, 0, 0);
    DRV_IOW_FIELD_NZ(lchip, NetRxWrEnCtl_t, NetRxWrEnCtl_cfgWrEn1_f, value_arr, write_st, 0, 0);
    DRV_IOW_FIELD_NZ(lchip, NetRxWrEnCtl_t, NetRxWrEnCtl_cfgWrEn2_f, value_arr, write_st, 0, 0);
    DRV_IOW_FIELD_NZ(lchip, NetRxWrEnCtl_t, NetRxWrEnCtl_cfgWrEn3_f, value_arr, write_st, 0, 0);
    cmd = DRV_IOW(NetRxWrEnCtl_t, DRV_ENTRY_FLAG);
    index = DRV_INS(0, 0);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, write_st));

    /*CtcTcamCtlReset*/
    value = 0;
    cmd = DRV_IOR(CtcTcamCtlReset_t, DRV_ENTRY_FLAG);
    index = DRV_INS(0, 0);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, write_st));
    DRV_IOW_FIELD_NZ(lchip, CtcTcamCtlReset_t, CtcTcamCtlReset_resetCoreProgramAclLtidTcam_f, &value, write_st, 0, 0);
    DRV_IOW_FIELD_NZ(lchip, CtcTcamCtlReset_t, CtcTcamCtlReset_resetCoreProgramAclTcam_f, &value, write_st, 0, 0);
    DRV_IOW_FIELD_NZ(lchip, CtcTcamCtlReset_t, CtcTcamCtlReset_resetCoreSupSensor_f, &value, write_st, 0, 0);
    cmd = DRV_IOW(CtcTcamCtlReset_t, DRV_ENTRY_FLAG);
    index = DRV_INS(0, 0);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, write_st));

    return CTC_E_NONE;

}

STATIC int32
_sys_tmg_datapath_init_module(uint8 lchip)
{
    uint32 cmd = 0;
    uint32 index = 0;
    uint32 value = 0;
    uint8  i = 0;
#ifndef EMULATION_ENV
    uint8  dp;
    uint32 entry_id = 0;
    EpePktProcFlexTunnelCtl_m epe_pkt;
    uint32 value_array[8];
#endif

    DP_DEBUG_FUNCTION_CALLED_PRINT();
    /*1. set init*/
    value = 1;

    for (i = 0; i < 2; i++)
    {
        index = DRV_INS(i, 0);
        cmd = DRV_IOW(NetRxInit_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &value));
    }

    for (i = 0; i < 2; i++)
    {
        index = DRV_INS(i, 0);
        cmd = DRV_IOW(BufRetrvDPInit_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &value));
    }

    cmd = DRV_IOW(BufRetrvShareInit_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &value));

    cmd = DRV_IOW(BufStoreProcInit_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &value));

    for (i = 0; i < 2; i++)
    {
        index = DRV_INS(i, 0);
        cmd = DRV_IOW(BufStoreDpCtlInit_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &value));
    }

    cmd = DRV_IOW(MetFifoProcInit_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &value));

    cmd = DRV_IOW(MetFifoShareInit_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &value));

    for (i = 0; i < 2; i++)
    {
        index = DRV_INS(i, 0);
        cmd = DRV_IOW(EpeScheduleInit_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &value));

        cmd = DRV_IOW(NetTxInit_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &value));

        cmd = DRV_IOW(NetRxInit_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &value));
    }

    cmd = DRV_IOW(IpeHdrAdjInit_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &value));

    cmd = DRV_IOW(IpeIntfMapInit_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &value));

    cmd = DRV_IOW(IpeLkupMgrInit_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &value));

    cmd = DRV_IOW(IpePktProcInit_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &value));

    for(i = 0; i < 3; i++)
    {
        index = DRV_INS(i, 0);
        cmd = DRV_IOW(ParserInit_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &value));
    }

    cmd = DRV_IOW(IpeFwdInit_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &value));

    cmd = DRV_IOW(DynamicAdInit_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &value));

    cmd = DRV_IOW(DynamicMiscKeyInit_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &value));

    cmd = DRV_IOW(EpeAclOamInit_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &value));

    cmd = DRV_IOW(EpeHdrAdjInit_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &value));

    cmd = DRV_IOW(EpeHdrProcInit_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &value));

    cmd = DRV_IOW(EpeNextHopInit_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &value));

    cmd = DRV_IOW(QMgrDeqChanInit_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &value));

    cmd = DRV_IOW(QMgrDeqL0Init_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &value));

    cmd = DRV_IOW(QMgrDeqL4CosInit_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &value));

    cmd = DRV_IOW(QMgrDeqL4GrpInit_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &value));

    cmd = DRV_IOW(QMgrDeqL4QueInit_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &value));

    cmd = DRV_IOW(QMgrDeqShpInit_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &value));

    cmd = DRV_IOW(QMgrErmInit_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &value));

    cmd = DRV_IOW(QMgrQWriteInit_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &value));

#ifndef EMULATION_ENV
    cmd = DRV_IOW(QMgrShellInit_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &value));
#endif

    cmd = DRV_IOW(StormCtlInit_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &value));

    cmd = DRV_IOW(EpeHdrEditInit_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &value));

    cmd = DRV_IOW(EpePktRewriteInit_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &value));

    for(i = 0; i < 21; i++)
    {
        index = DRV_INS(i, 0);
        cmd = DRV_IOW(QuadSgmacInit_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &value));
    }

    for (i = 0; i < 3; i++)
    {
        index = DRV_INS(i, 0);
        cmd = DRV_IOW(FlexDecodeInit_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &value));
    }

    for (i = 0; i < 2; i++)
    {
        index = DRV_INS(i, 0);
        cmd = DRV_IOW(MdioInit_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &value));
    }

    for (i = 0; i < 2; i++)
    {
        index = DRV_INS(i, 0);

        cmd = DRV_IOW(LedInit_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &value));
    }

    cmd = DRV_IOW(I2CMasterInit0_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &value));

    cmd = DRV_IOW(I2CMasterInit1_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &value));

    cmd = DRV_IOW(QMgrMsgMiscInit_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &value));

    cmd = DRV_IOW(DmaCtlInit_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &value));
#ifndef EMULATOR_ENV
    cmd = DRV_IOW(EcpuIntfInit_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &value));
#endif
    cmd = DRV_IOW(CpuMapInit_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &value));

    /*for (i = 0; i < 11; i++)
    {
        index = DRV_INS(i, 0);
        cmd = DRV_IOW(McuIntfInit_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &value));
        DMPS_DUMP_PRINT("write McuIntfInit 0 init 1 inst %d\n", i);
    }*/
#ifndef EMULATOR_ENV
    cmd = DRV_IOW(ScpuIntfInit_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &value));
#endif
#ifdef EMULATION_ENV
    sal_task_sleep(5000);
#else
    /*2. check init done */
    sal_task_sleep(1);

    if (0 == SDK_WORK_PLATFORM)
    {
        for (i = 0; i < 2; i++)
        {
            index = DRV_INS(i, 0);
            cmd = DRV_IOR(NetRxInitDone_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &value));
            if (!value)
            {
                SYS_DATAPATH_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, " [NetRxInit.%d] Feature not initialized \n", i);
                return CTC_E_NOT_INIT;
            }
        }

        for (i = 0; i < 2; i++)
        {
            index = DRV_INS(i, 0);
            cmd = DRV_IOR(BufRetrvDPInitDone_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &value));
            if (!value)
            {
                SYS_DATAPATH_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, " [BufRetrvDPInit.%d] Feature not initialized \n", i);
                return CTC_E_NOT_INIT;
            }
        }

        cmd = DRV_IOR(BufRetrvShareInitDone_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &value));
        if (!value)
        {
            SYS_DATAPATH_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, " [BufRetrvShareInit] Feature not initialized \n");
            return CTC_E_NOT_INIT;
        }

        cmd = DRV_IOR(BufStoreProcInitDone_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &value));
        if (!value)
        {
            SYS_DATAPATH_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, " [BufStoreProcInit] Feature not initialized \n");
            return CTC_E_NOT_INIT;
        }

        for (i = 0; i < 2; i++)
        {
            index = DRV_INS(i, 0);
            cmd = DRV_IOR(BufStoreDpCtlInitDone_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &value));
            if (!value)
            {
                SYS_DATAPATH_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, " [BufStoreDpCtlInit.%d] Feature not initialized \n", i);
                return CTC_E_NOT_INIT;
            }
        }

        cmd = DRV_IOR(MetFifoProcInitDone_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &value));
        if (!value)
        {
            SYS_DATAPATH_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, " [MetFifoProcInit] Feature not initialized \n");
            return CTC_E_NOT_INIT;
        }

        cmd = DRV_IOR(MetFifoShareInitDone_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &value));
        if (!value)
        {
            SYS_DATAPATH_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, " [MetFifoShareInit] Feature not initialized \n");
            return CTC_E_NOT_INIT;
        }

        for (i = 0; i < 2; i++)
        {
            index = DRV_INS(i, 0);
            cmd = DRV_IOR(EpeScheduleInitDone_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &value));
            if (!value)
            {
                SYS_DATAPATH_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, " [EpeScheduleInit.%d] Feature not initialized \n", i);
                return CTC_E_NOT_INIT;
            }

            cmd = DRV_IOR(NetTxInitDone_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &value));
            if (!value)
            {
                SYS_DATAPATH_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, " [NetTxInit.%d] Feature not initialized \n", i);
                return CTC_E_NOT_INIT;
            }

            cmd = DRV_IOR(NetRxInitDone_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &value));
            if (!value)
            {
                SYS_DATAPATH_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, " [NetRxInit.%d] Feature not initialized \n", i);
                return CTC_E_NOT_INIT;
            }

        }

        cmd = DRV_IOR(IpeHdrAdjInitDone_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &value));
        if(!value)
        {
            SYS_DATAPATH_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, " [IpeHdrAdjInitDone.initDone] Feature not initialized \n");
            return CTC_E_NOT_INIT;
        }

        cmd = DRV_IOR(IpeIntfMapInitDone_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &value));
        if(!value)
        {
            SYS_DATAPATH_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, " [IpeIntfMapInitDone.initDone] Feature not initialized \n");
            return CTC_E_NOT_INIT;
        }

        cmd = DRV_IOR(IpeLkupMgrInitDone_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &value));
        if(!value)
        {
            SYS_DATAPATH_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, " [IpeLkupMgrInitDone.initDone] Feature not initialized \n");
            return CTC_E_NOT_INIT;
        }

        cmd = DRV_IOR(IpePktProcInitDone_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &value));
        if(!value)
        {
            SYS_DATAPATH_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, " [IpePktProcInitDone.initDone] Feature not initialized \n");
            return CTC_E_NOT_INIT;
        }

        cmd = DRV_IOR(IpeFwdInitDone_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &value));
        if(!value)
        {
            SYS_DATAPATH_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, " [IpeFwdInitDone.initDone] Feature not initialized \n");
            return CTC_E_NOT_INIT;
        }

        cmd = DRV_IOR(DynamicAdInitDone_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &value));
        if(!value)
        {
            SYS_DATAPATH_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, " [DynamicAdInitDone.initDone] Feature not initialized \n");
            return CTC_E_NOT_INIT;
        }

        cmd = DRV_IOR(DynamicMiscKeyInitDone_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &value));
        if(!value)
        {
            SYS_DATAPATH_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, " [DynamicMiscKeyInitDone.initDone] Feature not initialized \n");
            return CTC_E_NOT_INIT;
        }

        cmd = DRV_IOR(EpeAclOamInitDone_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &value));
        if(!value)
        {
            SYS_DATAPATH_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, " [EpeAclOamInitDone.initDone] Feature not initialized \n");
            return CTC_E_NOT_INIT;
        }

        cmd = DRV_IOR(EpeHdrAdjInitDone_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &value));
        if(!value)
        {
            SYS_DATAPATH_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, " [EpeHdrAdjInitDone.initDone] Feature not initialized \n");
            return CTC_E_NOT_INIT;
        }

        cmd = DRV_IOR(EpeHdrProcInitDone_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &value));
        if(!value)
        {
            SYS_DATAPATH_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, " [EpeHdrProcInitDone.initDone] Feature not initialized \n");
            return CTC_E_NOT_INIT;
        }

        cmd = DRV_IOR(EpeNextHopInitDone_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &value));
        if(!value)
        {
            SYS_DATAPATH_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, " [EpeNextHopInitDone.initDone] Feature not initialized \n");
            return CTC_E_NOT_INIT;
        }

        cmd = DRV_IOR(QMgrDeqChanInitDone_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &value));
        if(!value)
        {
            SYS_DATAPATH_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, " [QMgrDeqChanInitDone.initDone] Feature not initialized \n");
            return CTC_E_NOT_INIT;
        }

        cmd = DRV_IOR(QMgrDeqL0InitDone_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &value));
        if(!value)
        {
            SYS_DATAPATH_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, " [QMgrDeqL0InitDone.initDone] Feature not initialized \n");
            return CTC_E_NOT_INIT;
        }

        cmd = DRV_IOR(QMgrDeqL4CosInitDone_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &value));
        if(!value)
        {
            SYS_DATAPATH_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, " [QMgrDeqL4CosInitDone.initDone] Feature not initialized \n");
            return CTC_E_NOT_INIT;
        }

        cmd = DRV_IOR(QMgrDeqL4GrpInitDone_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &value));
        if(!value)
        {
            SYS_DATAPATH_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, " [QMgrDeqL4GrpInitDone.initDone] Feature not initialized \n");
            return CTC_E_NOT_INIT;
        }

        cmd = DRV_IOR(QMgrDeqL4QueInitDone_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &value));
        if(!value)
        {
            SYS_DATAPATH_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, " [QMgrDeqL4QueInitDone.initDone] Feature not initialized \n");
            return CTC_E_NOT_INIT;
        }

        cmd = DRV_IOR(QMgrDeqShpInitDone_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &value));
        if(!value)
        {
            SYS_DATAPATH_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, " [QMgrDeqShpInitDone.initDone] Feature not initialized \n");
            return CTC_E_NOT_INIT;
        }

        cmd = DRV_IOR(QMgrErmInitDone_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &value));
        if(!value)
        {
            SYS_DATAPATH_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, " [QMgrErmInitDone.initDone] Feature not initialized \n");
            return CTC_E_NOT_INIT;
        }

        cmd = DRV_IOR(QMgrQWriteInitDone_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &value));
        if(!value)
        {
            SYS_DATAPATH_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, " [QMgrQWriteInitDone.initDone] Feature not initialized \n");
            return CTC_E_NOT_INIT;
        }

#ifndef EMULATION_ENV
        cmd = DRV_IOR(QMgrShellInitDone_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &value));
        if(!value)
        {
            SYS_DATAPATH_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, " [QMgrShellInitDone.initDone] Feature not initialized \n");
            return CTC_E_NOT_INIT;
        }
#endif

        cmd = DRV_IOR(StormCtlInitDone_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &value));
        if(!value)
        {
            SYS_DATAPATH_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, " [StormCtlInitDone.initDone] Feature not initialized \n");
            return CTC_E_NOT_INIT;
        }

        cmd = DRV_IOR(EpeHdrEditInitDone_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &value));
        if(!value)
        {
            SYS_DATAPATH_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, " [EpeHdrEditInitDone.initDone] Feature not initialized \n");
            return CTC_E_NOT_INIT;
        }

        cmd = DRV_IOR(EpePktRewriteInitDone_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &value));
        if(!value)
        {
            SYS_DATAPATH_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, " [EpePktRewriteInitDone.initDone] Feature not initialized \n");
            return CTC_E_NOT_INIT;
        }

        for (i = 0; i < 21; i++)
        {
            index = DRV_INS(i, 0);
            cmd = DRV_IOR(QuadSgmacInitDone_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &value));
            if(!value)
            {
                SYS_DATAPATH_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, " [QuadSgmacInitDone.initDone] Feature not initialized \n");
                return CTC_E_NOT_INIT;
            }
        }

        for (i = 0; i < 3; i++)
        {
            index = DRV_INS(i, 0);
            cmd = DRV_IOR(FlexDecodeInitDone_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &value));
            if (!value)
            {
                SYS_DATAPATH_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, " [FlexDecodeInitDone.%d] Feature not initialized \n", i);
                return CTC_E_NOT_INIT;
            }
        }

        index = 0;
        cmd = DRV_IOR(I2CMasterInitDone0_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &value));
        if (!value)
        {
            SYS_DATAPATH_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, " [I2CMasterInitDone0.%d] Feature not initialized \n", i);
            return CTC_E_NOT_INIT;
        }
        cmd = DRV_IOR(I2CMasterInitDone1_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &value));
        if (!value)
        {
            SYS_DATAPATH_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, " [I2CMasterInitDone1.%d] Feature not initialized \n", i);
            return CTC_E_NOT_INIT;
        }

        for (i = 0; i < 2; i++)
        {
            index = DRV_INS(i, 0);

            cmd = DRV_IOR(LedInitDone_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &value));
            if (!value)
            {
                SYS_DATAPATH_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, " [LedInitDone.%d] Feature not initialized \n", i);
                return CTC_E_NOT_INIT;
            }
        }

        cmd = DRV_IOR(QMgrMsgMiscInitDone_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &value));
        if(!value)
        {
            SYS_DATAPATH_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, " [QMgrMsgMiscInitDone.initDone] Feature not initialized \n");
            return CTC_E_NOT_INIT;
        }

        /*special operation for wb reload: skip DmaCtlInitDone check in wb reload*/
        if(p_drv_master[lchip]->wb_status != DRV_WB_STATUS_RELOADING)
        {
            cmd = DRV_IOR(DmaCtlInitDone_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &value));
            if(!value)
            {
                SYS_DATAPATH_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, " [DmaCtlInitDone.initDone]1 Feature not initialized \n");
                return CTC_E_NOT_INIT;
            }
        }

        cmd = DRV_IOR(EcpuIntfInitDone_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &value));
        if(!value)
        {
            SYS_DATAPATH_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, " [EcpuIntfInitDone.initDone] Feature not initialized \n");
            return CTC_E_NOT_INIT;
        }

        cmd = DRV_IOR(CpuMapInitDone_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &value));
        if(!value)
        {
            SYS_DATAPATH_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, " [CpuMapInitDone.initDone] Feature not initialized \n");
            return CTC_E_NOT_INIT;
        }

        /*for (i = 0; i < 11; i++)
        {
            index = DRV_INS(i, 0);
            cmd = DRV_IOR(McuIntfInitDone_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &value));
            if (!value)
            {
                SYS_DATAPATH_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, " [McuIntfInit.%d] Feature not initialized \n", i);
                return CTC_E_NOT_INIT;
            }
        }*/

        cmd = DRV_IOR(ScpuIntfInitDone_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &value));
        if(!value)
        {
            SYS_DATAPATH_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, " [ScpuIntfInitDone.initDone] Feature not initialized \n");
            return CTC_E_NOT_INIT;
        }

        /*init done additional cfg*/

        /*QWriteCtl.cfgSingleBufferUnit write 432*/
        cmd = DRV_IOR(QWriteCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, value_array));
        value = 432;
        DRV_IOW_FIELD(lchip, QWriteCtl_t, QWriteCtl_cfgSingleBufferUnit_f, &value, value_array);
        cmd = DRV_IOW(QWriteCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, value_array));

        /*BufStoreMiscResrcCongestionStateCtl.totalBufCongestionThrd write 0x137fc*/
        for(dp = 0; dp < SYS_TMG_DP_NUM; dp++)
        {
            entry_id = DRV_INS(dp, 0);
            cmd = DRV_IOR(BufStoreMiscResrcCongestionStateCtl_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, entry_id, cmd, value_array));
            value = 0x137fc;
            DRV_IOW_FIELD(lchip, BufStoreMiscResrcCongestionStateCtl_t,
                BufStoreMiscResrcCongestionStateCtl_totalBufCongestionThrd_f, &value, value_array);
            cmd = DRV_IOW(BufStoreMiscResrcCongestionStateCtl_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, entry_id, cmd, value_array));
        }

        /*EpeAclOamCreditCtl.epeOamHashTrackCreditThrd write 15*/
        cmd = DRV_IOR(EpeAclOamCreditCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, value_array));
        value = 15;
        DRV_IOW_FIELD(lchip, EpeAclOamCreditCtl_t, EpeAclOamCreditCtl_epeOamHashTrackCreditThrd_f, &value, value_array);
        cmd = DRV_IOW(EpeAclOamCreditCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, value_array));

        /*IpeHdrAdjReserved.reserved write 0x8073*/
        cmd = DRV_IOR(IpeHdrAdjReserved_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, value_array));
        value = 0x8073;
        DRV_IOW_FIELD(lchip, IpeHdrAdjReserved_t, IpeHdrAdjReserved_reserved_f, &value, value_array);
        cmd = DRV_IOW(IpeHdrAdjReserved_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, value_array));

        /*QMgrMsgMiscDrainEnable.freePtrDrainEnable write 1*/
        cmd = DRV_IOR(QMgrMsgMiscDrainEnable_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, value_array));
        value = 1;
        DRV_IOW_FIELD(lchip, QMgrMsgMiscDrainEnable_t, QMgrMsgMiscDrainEnable_freePtrDrainEnable_f, &value, value_array);
        cmd = DRV_IOW(QMgrMsgMiscDrainEnable_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, value_array));

        /*EpePktProcFlexTunnelCtl.flexArray_[0~7]_flexHdrTemplate write 0*/
        cmd = DRV_IOR(EpePktProcFlexTunnelCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &epe_pkt));
        value_array[0] = 0; //128bit 0
        value_array[1] = 0;
        value_array[2] = 0;
        value_array[3] = 0;
        DRV_IOW_FIELD(lchip, EpePktProcFlexTunnelCtl_t, EpePktProcFlexTunnelCtl_flexArray_0_flexHdrTemplate_f, value_array, &epe_pkt);
        DRV_IOW_FIELD(lchip, EpePktProcFlexTunnelCtl_t, EpePktProcFlexTunnelCtl_flexArray_1_flexHdrTemplate_f, value_array, &epe_pkt);
        DRV_IOW_FIELD(lchip, EpePktProcFlexTunnelCtl_t, EpePktProcFlexTunnelCtl_flexArray_2_flexHdrTemplate_f, value_array, &epe_pkt);
        DRV_IOW_FIELD(lchip, EpePktProcFlexTunnelCtl_t, EpePktProcFlexTunnelCtl_flexArray_3_flexHdrTemplate_f, value_array, &epe_pkt);
        DRV_IOW_FIELD(lchip, EpePktProcFlexTunnelCtl_t, EpePktProcFlexTunnelCtl_flexArray_4_flexHdrTemplate_f, value_array, &epe_pkt);
        DRV_IOW_FIELD(lchip, EpePktProcFlexTunnelCtl_t, EpePktProcFlexTunnelCtl_flexArray_5_flexHdrTemplate_f, value_array, &epe_pkt);
        DRV_IOW_FIELD(lchip, EpePktProcFlexTunnelCtl_t, EpePktProcFlexTunnelCtl_flexArray_6_flexHdrTemplate_f, value_array, &epe_pkt);
        DRV_IOW_FIELD(lchip, EpePktProcFlexTunnelCtl_t, EpePktProcFlexTunnelCtl_flexArray_7_flexHdrTemplate_f, value_array, &epe_pkt);
        cmd = DRV_IOW(EpePktProcFlexTunnelCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &epe_pkt));

        /*IpeHeaderAdjustCpuChanCtl.fromCpuEn write 0*/
        sal_memset(value_array, 0, 8*sizeof(uint32));
        cmd = DRV_IOW(IpeHeaderAdjustCpuChanCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, value_array));

        /*OamParserCreditCtl.hdrAdjHdrEditCreditHighThrd write 47*/
        cmd = DRV_IOR(OamParserCreditCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, value_array));
        value = 47;
        DRV_IOW_FIELD(lchip, OamParserCreditCtl_t, OamParserCreditCtl_hdrAdjHdrEditCreditHighThrd_f, &value, value_array);
        cmd = DRV_IOW(OamParserCreditCtl_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, value_array));

        /*RefDivSpnOamTxPulse.cfgRefDivSpnOamTxPulse write 0x500*/
        cmd = DRV_IOR(RefDivSpnOamTxPulse_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, value_array));
        value = 0x500;
        DRV_IOW_FIELD(lchip, RefDivSpnOamTxPulse_t, RefDivSpnOamTxPulse_cfgRefDivSpnOamTxPulse_f, &value, value_array);
        cmd = DRV_IOW(RefDivSpnOamTxPulse_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, value_array));

    }
#endif

    DP_DEBUG_FUNCTION_RETURN_PRINT();
    
    return CTC_E_NONE;
}

STATIC int32
_sys_tmg_datapath_init_serdes(uint8 lchip, ctc_datapath_global_cfg_t* p_datapath_cfg)
{
    return CTC_E_NONE;
}

int32
_sys_tmg_datapath_init_extra_cfg_dp(uint8 lchip, uint8 dp_id)
{
    uint32 cmd            = 0;
    uint32 val_32         = 0;
    uint32 entry_id       = 0;
    uint32 dp_chan_id     = 0;
    uint32 chan_id        = 0;
    DsChannelizeMode_m    mode;
    BrPrioritySelect_m    priority_sel;
    BufStoreProcFifoCtl_m bs_ctl;

    /*config max len*/
    for(dp_chan_id = 0; dp_chan_id < SYS_TMG_CHANNEL_NUM_PER_DP; dp_chan_id++)
    {
        entry_id = DRV_INS(dp_id, dp_chan_id); // every DP has one instance
        cmd = DRV_IOR(DsChannelizeMode_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, entry_id, cmd, &mode));
        val_32 = 0;
        DRV_IOW_FIELD_NZ(lchip, DsChannelizeMode_t, DsChannelizeMode_portMinLen_f, &val_32, &mode, dp_id, dp_chan_id);
        val_32 = 9600;
        DRV_IOW_FIELD_NZ(lchip, DsChannelizeMode_t, DsChannelizeMode_portMaxLen_f, &val_32, &mode, dp_id, dp_chan_id);
        cmd = DRV_IOW(DsChannelizeMode_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, entry_id, cmd, &mode));
    }
    for(dp_chan_id = 0; dp_chan_id < SYS_TMG_CHANNEL_NUM_PER_DP*2; dp_chan_id++)
    {
        chan_id  = dp_id*SYS_TMG_CHANNEL_NUM_PER_DP*2 + dp_chan_id;
        entry_id = DRV_INS(0, chan_id);     // only one instance
        cmd = DRV_IOR(BrPrioritySelect_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, entry_id, cmd, &priority_sel));
        val_32 = (0 == dp_id) ? (chan_id%2 + 1) : (2 - chan_id%2);
        DRV_IOW_FIELD_NZ(lchip, BrPrioritySelect_t, BrPrioritySelect_brPrioritySelect_f, &val_32, &priority_sel, 0, chan_id);
        cmd = DRV_IOW(BrPrioritySelect_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, entry_id, cmd, &priority_sel));
    }

    /*set BufStoreProcFifoCtl.bsIpeFreePtrFifoSlice0Dp0/1AEmptyThrd 38*/
    entry_id = DRV_INS(0, 0);
    cmd = DRV_IOR(BufStoreProcFifoCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, entry_id, cmd, &bs_ctl));
    val_32 = 38;
    DRV_IOW_FIELD_NZ(lchip, BufStoreProcFifoCtl_t, BufStoreProcFifoCtl_bsIpeFreePtrFifoSlice0Dp0AEmptyThrd_f + dp_id, &val_32, &bs_ctl, 0, 0);
    cmd = DRV_IOW(BufStoreProcFifoCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, entry_id, cmd, &bs_ctl));

    DP_DEBUG_FUNCTION_RETURN_PRINT();

    return CTC_E_NONE;
}

int32
_sys_tmg_datapath_nettx_common_calendar(uint8 lchip, uint8 dp_id, uint8 dp_txqm_id, uint8 *p_error, 
                                                     uint16 *p_walk_end, uint16 *p_cal, sys_cal_info_collect_t* cal_info)
{
    int32  ret                  = CTC_E_NONE;
    uint8  txqm_mac_client      = 0;
    uint16 dp_mac_client        = 0;
    uint32 speed                = 0;
    uint32 speed_org            = 0;
    uint32 speed_2nd            = 0;
    uint32 speed_2nd_sum        = 0;
    uint32 speed_2nd_violation  = 0;
    uint32 speed_2nd_sum_max    = 0;
    uint16 core_pll             = 0;
    int16  cal_entry_num        = SYS_TMG_NETTX_MAX_CAL_LEN_PER_TXQM;
    uint32 speed_list[SYS_TMG_MAC_CLIENT_NUM_PER_TXQM]     = {0};
    uint32 speed_list_2nd[SYS_TMG_MAC_CLIENT_NUM_PER_TXQM] = {0};

    SYS_DATAPATH_DBG_OUT(CTC_DEBUG_LEVEL_FUNC, "%s\n", __FUNCTION__);
    SYS_DATAPATH_DBG_OUT(CTC_DEBUG_LEVEL_PARAM,"lchip %u, dp_id %u, dp_txqm_id %u\n", lchip, dp_id, dp_txqm_id);

    for(txqm_mac_client = 0; txqm_mac_client < SYS_TMG_MAC_CLIENT_NUM_PER_TXQM; txqm_mac_client ++)
    {
        dp_mac_client = dp_txqm_id * SYS_TMG_MAC_CLIENT_NUM_PER_TXQM + txqm_mac_client;
        speed_org = cal_info[dp_mac_client].speed;

        speed = speed_org;
        speed_2nd = speed_org;

        //speed = (((speed_org > 0) && (speed_org < 1)) ? 1 : speed);
        speed_2nd = (((speed_org > 0) && (speed_org < 5)) ? 5 : speed_2nd);

        speed_list[txqm_mac_client] = ((2 == speed) ? 25 : (speed * 10));        /* 2.5G */
        speed_list_2nd[txqm_mac_client] = speed_2nd * 10;             /* x.5G */

        speed_2nd_sum += speed_list_2nd[txqm_mac_client];
    }

    /* stage2 : violation detect (very important !!!!!! ) */
    ///TODO: change?
    CTC_ERROR_RETURN(sys_usw_dmps_db_get_core_pll(lchip, &core_pll, 1));
    speed_2nd_sum_max = 10 * SYS_TMG_TXQM_SPECIAL_BW_MAX_G * core_pll / SYS_TMG_CLK_DEFAULT;
    speed_2nd_violation = ((speed_2nd_sum > speed_2nd_sum_max) ? 1 : 0);

    /* stage3 : calculate calendar use common_calendar */
    if(speed_2nd_violation)
    {
        CTC_ERROR_RETURN(_sys_tmg_datapath_common_calendar(cal_entry_num, SYS_TMG_MAX_MAC_NUM_PER_TXQM, speed_list, 
                                                         p_error, p_walk_end, p_cal));
    }
    else
    {
        CTC_ERROR_RETURN(_sys_tmg_datapath_common_calendar(cal_entry_num, SYS_TMG_MAX_MAC_NUM_PER_TXQM, speed_list_2nd, 
                                                         p_error, p_walk_end, p_cal));
    }

    /* if TXQM is empty */
    if(0 == speed_2nd_sum)
    {
        *p_walk_end = 0;
    }

    return ret;
}

int32
_sys_tmg_datapath_calculate_nettx_calendar(uint8 lchip, uint8 dp_id, uint32 dp_txqm_id, 
                                                         uint16 *p_cal, uint16* walk_end, sys_cal_info_collect_t* cal_info)
{
    uint8  mactx_reorder_en[SYS_TMG_MAC_CLIENT_NUM_PER_TXQM]    = {0};
    uint32 interval[SYS_TMG_MAC_CLIENT_NUM_PER_TXQM]            = {0};/*interval,per port*/
    uint32 interval_cp[SYS_TMG_MAC_CLIENT_NUM_PER_TXQM+1]       = {0};/*interval,per port*/
    uint32 interval_order[SYS_TMG_MAC_CLIENT_NUM_PER_TXQM]      = {0};/*interval,per port*/
    uint8  active[SYS_TMG_MAC_CLIENT_NUM_PER_TXQM+1]            = {0};/*active list*/
    uint8  en[SYS_TMG_MAC_CLIENT_NUM_PER_TXQM]                  = {0};/*port enable*/
    uint8  first_cal_record_en[SYS_TMG_MAC_CLIENT_NUM_PER_TXQM] = {0};/*record the index first select*/
    uint32 speed_sum        = 0;
    uint32 speed            = 0;
    uint32 oversub_bw       = 300; ///TODO: change ?
    uint8  oversub_flag     = FALSE;
    uint32 member_num       = 0;
    uint32  bw_ratio        = 1000;
    /*uint8  spd_2nd_flag   = FALSE;*/
    /*uint8  spd_2nd_lock   = 0;*/
    uint8  spd_max_lock     = 0;
    uint8  low_prio         = FALSE;
    uint32 cycle            = 0;  /*calendar cycle*/
    uint8  done             = FALSE;
    uint8  error            = FALSE;
    uint8  force_sel        = FALSE;
    uint32 min_id           = 1;
    uint32 min_intv         = 10000;
    uint8  min_index        = 0;
    uint8  exchange_flag    = 0;
    uint32 selport          = 0;
    uint8  extra            = FALSE;
    uint8  active_flag      = FALSE;
    uint8  illegal          = FALSE;
    uint8  reload_active    = FALSE;
    uint8  mactx_illegal    = 0;
    uint8  i                = 0; 
    uint8  k                = 0;
    uint16 dp_mac_id        = 0;
    uint32 actual_interval  = 0;
    uint32 expect_interval  = 0;
    uint32 multi_factor     = 1000;
    uint32 last_gap         = 0;
    uint32 interval_new     = 0;
    uint32 interval_sum     = 0;
    uint32 active_index_chg_dis = 0;
    uint32 intervalChk      = 0;
    uint32 intv_future      = 0;
    uint32 intv_future2     = 0;
    uint32 intv_margine     = 0;
    int32  ret = CTC_E_NONE;
    sys_tmg_nettx_cal_heap_t* p_heap = NULL;
   
    done = FALSE;
    error = FALSE;
    cycle = 0;
    speed_sum = 0;
    speed = 0;
    oversub_bw = 300;
    oversub_flag = FALSE;
    member_num = 0;
    bw_ratio = 1000;

    p_heap = (sys_tmg_nettx_cal_heap_t*)mem_malloc(MEM_DMPS_MODULE, sizeof(sys_tmg_nettx_cal_heap_t));
    CTC_ERROR_GOTO((NULL == p_heap) ? CTC_E_NO_MEMORY : CTC_E_NONE, ret, RELEASE_PTR_RETURN_1);
    sal_memset(p_heap, 0, sizeof(sys_tmg_nettx_cal_heap_t));

    /*initial phase*/
    for(i = 0; i < SYS_TMG_MAC_CLIENT_NUM_PER_TXQM; i++)
    {
        dp_mac_id = dp_txqm_id * SYS_TMG_MAC_CLIENT_NUM_PER_TXQM + i;
        speed = cal_info[dp_mac_id].speed;
        speed_sum += speed;
        p_heap->first_cal_record[i] = 0;
        first_cal_record_en[i] = TRUE;
        p_heap->cnt_history[i] = 0;
    }

    if(speed_sum > oversub_bw)
    {
        oversub_flag = 1;
    }
    /*else 
    {
        bw_ratio = speed_sum * 1000 / 300;
    }*/

    /*look up low priority speed, inherit from Duet2*/
    /*spd_2nd_flag = FALSE;*/
    /*spd_2nd_lock = 0;*/
    spd_max_lock = 0;

    for(i = 0; i < SYS_TMG_MAC_CLIENT_NUM_PER_TXQM; i++)
    {
        dp_mac_id = dp_txqm_id * SYS_TMG_MAC_CLIENT_NUM_PER_TXQM + i;
        speed = cal_info[dp_mac_id].speed;
        if((1 <= speed) && (spd_max_lock < speed))
        {
            /*if((0 != spd_2nd_lock) && (spd_2nd_lock < spd_max_lock))
            {
                spd_2nd_flag = TRUE;
            }*/
            /*spd_2nd_lock = spd_max_lock;*/
            spd_max_lock = speed;
        }
    }
    for(i = 0; i < SYS_TMG_MAC_CLIENT_NUM_PER_TXQM; i++)
    {
        dp_mac_id = dp_txqm_id * SYS_TMG_MAC_CLIENT_NUM_PER_TXQM + i;
        speed = cal_info[dp_mac_id].speed;
        low_prio = oversub_flag && (spd_max_lock != speed);
        /*initial interval*/
        (void)_sys_tmg_dp_calculate_interval(lchip, speed, 1, low_prio, 0, 1, bw_ratio, &interval_new, &(p_heap->cnt_history[i]));
        interval[i] = interval_new;
        /*initial active / enable and num*/
        if(1 <= speed)
        {
            active[i] = TRUE;
            en[i] = TRUE;
            p_heap->num[i] = 1;
            member_num++;
        }
        else  /*invalid port*/
        {
            active[i] = FALSE;
            en[i] = FALSE;
            p_heap->num[i] = 1;
            //member_num++;
        }
    }

    /*main function*/
    while((!done) && (!error))
    {
        /*reorder*/
        for(i = 1; i < SYS_TMG_MAC_CLIENT_NUM_PER_TXQM+1; i++)
        {
            interval_cp[i] = interval[i-1];
        }
        /*stage1. bubble sort*/
        for(i = 1; i <= member_num; i++)
        {
            min_id = 1;
            min_intv = 10000;

            for(k = 1; k <= SYS_TMG_MAC_CLIENT_NUM_PER_TXQM; k++)
            {
                if((interval_cp[k]) && (min_intv > interval_cp[k]))
                {
                    min_intv = interval_cp[k];
                    min_id = k;
                }
                else if((interval_cp[k]) && (min_intv == interval_cp[k]) && active[k])
                {
                    min_id = k;
                }
            }
            interval_cp[min_id] = 10000;
            interval_order[i] = min_intv;
            p_heap->portid_order[i] = min_id - 1;
        }

        /*stage2. calendar select*/
        min_index = p_heap->portid_order[1];  /*default min interval portid*/
        min_intv = interval_order[1];  /*default min interval*/

        /*interval violation deep check if reorder the minIndex*/
        active_index_chg_dis = 0;
        for(i = 1; i <= member_num; i++)
        {
            p_heap->expect_margine[i] = 1;
        }
        for(i = 1; i <= member_num; i++)
        {
            selport = p_heap->portid_order[i];

            dp_mac_id = dp_txqm_id * SYS_TMG_MAC_CLIENT_NUM_PER_TXQM + selport;
            speed = cal_info[dp_mac_id].speed;
            
            interval_sum = p_heap->cnt_history[selport];
            (void)_sys_tmg_dp_calculate_interval(lchip, speed, p_heap->num[selport], low_prio, extra, 0, bw_ratio, &intervalChk, &interval_sum);
            intv_future = interval_order[i] - 2 + intervalChk;
            intv_future2 = interval_order[i] - 2 + intervalChk * 2 - 1;

            if ( intv_future < member_num)
            {
                for ( k = intv_future; k <= member_num; k++)
                {
                    intv_margine = interval_order[k] - k;

                    if( intv_margine <= p_heap->expect_margine[k])
                    {
                        active_index_chg_dis = 1;
                    }

                    p_heap->expect_margine[k] ++;
                }
            }
            
            /*2nd*/
            /*means selPort will be a queue-jumper after reload interval*/
            if(intv_future2 < member_num)
            {
                for ( k = intv_future2; k <= member_num; k++)
                {
                    intv_margine = interval_order[k] - k;

                    if( intv_margine <= p_heap->expect_margine[k])
                    {
                        active_index_chg_dis = 1;
                    }

                    p_heap->expect_margine[k] ++;
                }
            }
        }
        
        /*add by zed to balance mac speed port bandwidth begin*/
        force_sel = 0;
        exchange_flag = 0;
        for (i = 1; i <= member_num; i++)
        {
            selport = p_heap->portid_order[i];

            dp_mac_id = dp_txqm_id * SYS_TMG_MAC_CLIENT_NUM_PER_TXQM + selport;
            speed = cal_info[dp_mac_id].speed;

            /*
             * exchange minIndex due to : 
             * 1: not the fastest speed
             * 2: doesn't set exchange_flag before
             * 3: doesn't set force_sel before
             * 4: could't exchange active index
             */
            if((speed != spd_max_lock) 
                   && (!exchange_flag)
                   && (!force_sel)
                   && (active_index_chg_dis))
            {
                min_index = p_heap->portid_order[i];
                exchange_flag = 1;
                min_intv = interval_order[i];
            }

            if(i == interval_order[i])
            {
                force_sel = 1;
            }
        }
        
        /*detect error*/
        force_sel = FALSE;
        exchange_flag = FALSE;
        for(i = 1; i <= member_num; i++)
        {
            if(i > interval_order[i])
            {
                error = 2;
                SYS_DATAPATH_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, 
                    "%% [nettx]automatic constrain failed! failed id = %u, interval = %u, cycle = %u\n", 
                    i, interval_order[i], cycle);
                for(k = 1; k <= member_num; k++)
                {
                    SYS_DATAPATH_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "%% [nettx]bubble sort index %u, interval %u\n", 
                        k, interval_order[k]) ;
                }
                break;
            } 
            /*get the mac id*/
            selport = p_heap->portid_order[i];
            /*exchange min_index due to : 
            1: must in active list 
            2: doesn't set exchange_flag before 
            3: doesn't set force_sel before 
            4: has small interval
            5: ~activeIndexChgDis*/
            if((active[selport]) && (!exchange_flag) && (!force_sel) && (!active_index_chg_dis))
            {
                min_index = p_heap->portid_order[i];
                exchange_flag = TRUE;
                min_intv = interval_order[i];
            }
            /*force_sel eq 1 means calendar can't select the portid_order index larger than i*/
            if(i == interval_order[i])
            {
                force_sel = TRUE;
            }
        }

        /*stage3. maintain DS*/
        /*stage3.1 all interval will decrease 1*/
        for(i = 0; i < SYS_TMG_MAC_CLIENT_NUM_PER_TXQM; i++)
        {
            if(en[i])   
            {
                interval[i]--;
            }
        }
        /*stage3.2 generage calendar data*/
        p_cal[cycle] = min_index;

        /*stage3.3  re-calulate interval*/
        dp_mac_id = dp_txqm_id * SYS_TMG_MAC_CLIENT_NUM_PER_TXQM + min_index;
        speed = cal_info[dp_mac_id].speed;
        extra = ((1 < min_intv) && force_sel);
        low_prio = oversub_flag && (!(spd_max_lock == speed));

        (void)_sys_tmg_dp_calculate_interval(lchip, speed, p_heap->num[min_index], low_prio, extra, 1, bw_ratio, &interval_new, &(p_heap->cnt_history[min_index]));
        interval[min_index] = interval_new;
        p_heap->num[min_index]++;  /*num++ after re-calculate interval*/
        active[min_index] = FALSE;

        /*stage3.4 record the first calendar cycle*/
        if(first_cal_record_en[min_index])
        {
            p_heap->first_cal_record[min_index] = cycle;
            first_cal_record_en[min_index] = FALSE;
        }

        /*stage4. finish calendar calculate*/
        /*4.1 detect active flag*/
        active_flag = FALSE;
        for(i = 0; i < SYS_TMG_MAC_CLIENT_NUM_PER_TXQM; i++)
        {
            if(active[i])
            {
                active_flag = TRUE;
            }
        }
        /*4.2 detect interval violation*/
        /*NetTx use 1*192+1 Byte to calculate interval average*/
        if(!active_flag)
        {
            illegal = FALSE;
            mactx_illegal = 0;
            /* mactx_has_violation in net tx */
            sal_memset(mactx_reorder_en, FALSE, SYS_TMG_MAC_CLIENT_NUM_PER_TXQM*sizeof(uint8));
            for(i = 0; i < SYS_TMG_MAC_CLIENT_NUM_PER_TXQM; i++)
            {
                dp_mac_id = dp_txqm_id * SYS_TMG_MAC_CLIENT_NUM_PER_TXQM + i;
                speed = cal_info[dp_mac_id].speed;
                mactx_reorder_en[i] = FALSE;
                /*port enable*/
                if(0 != speed)
                {
                    /*192*1+1 B could reach performance*/
                    ///TODO: change?
                    expect_interval = (SYS_TMG_MAC_CALENDAR_BUS_WIDTH_TX+20+1)* SYS_TMG_MAC_CALENDAR_CLK_MF * 8 / (speed*2);
                    actual_interval = ((cycle + 1) * multi_factor) / (p_heap->num[i] - 1);
                    if(actual_interval > expect_interval)
                    {
                        illegal = TRUE;
                        active[i] = TRUE;
                    }
                    /*tail --> head gap illegal calculate*/
                    last_gap = (p_heap->first_cal_record[i] > 2) ? (p_heap->first_cal_record[i] - 2) : 0;
                    last_gap = last_gap * bw_ratio / 1000;
                    /*last_gap = first_cal_record[i];*/
                    if(last_gap > interval[i])
                    {
                        illegal = TRUE;
                        active[i] = TRUE;
                    }
                }
            }
            /*special for MacTx*/
            /*adjust calendar if interval too small*/
            /*omitted*/
            /*becasue MacTx is abandoned, mactx_illegal is not funcational*/
            reload_active = (illegal || (0 != mactx_illegal));
            /*finish if no violation*/
            if(!reload_active)
            {
                done = TRUE;
                *walk_end = cycle;
            }
        }
        cycle++;
        if(128 < cycle)
        {
            error = 1;
            SYS_DATAPATH_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "%% [nettx]calendar cycle larger than 128, cycle %u \n", cycle);
        }
    }
    if(error)
    {
        SYS_DATAPATH_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "%% [nettx] NetTx calendar generate mistake ! error %u\n", error);
        ret = CTC_E_INVALID_PARAM;
        goto RELEASE_PTR_RETURN_2;
    }
    
RELEASE_PTR_RETURN_2:
    mem_free(p_heap);
RELEASE_PTR_RETURN_1:
    return ret;
}

uint32
_sys_tmg_datapath_nettx_cal_cfg(uint8 lchip, uint8 dp_id, uint32 dp_txqm_id, uint16* p_cal, uint16 walk_end)
{
    uint8  i           = 0;
    uint32 val_32      = 0;
    uint32 cmd         = 0;
    uint32 fld_id      = 0;
    uint32 entry_id    = 0;
    uint32 is_back_cal = 0;
    uint32 table       = 0;
    uint32 field       = 0;
    NetTxCal_m     nettx_cal;
    NetTxCalCtl_m  cal_ctl;
    NetTxMiscCtl_m misc_ctl;

    entry_id = DRV_INS(dp_id, 0);
    cmd      = DRV_IOR(NetTxMiscCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, entry_id, cmd, &misc_ctl));
    val_32   = GetNetTxMiscCtl(V, netTxReady_f, &misc_ctl);
    cmd      = DRV_IOR(NetTxCalCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, entry_id, cmd, &cal_ctl));
    dmps_NetTxCalCtl_calEntry0Sel_f(dp_txqm_id, fld_id);
    DRV_IOR_FIELD(lchip, NetTxCalCtl_t, fld_id, &is_back_cal, &cal_ctl);
    
    if(0 == val_32) is_back_cal = 0;
    else            is_back_cal = is_back_cal ? 0 : 1;

    /* NetTxCal/NetTxCalBak-- txqm 0: 0~63 ; txqm 1: 64_127; ... */
    /* entry */ 
    table = is_back_cal ? NetTxCalBak_t : NetTxCal_t;
    field = is_back_cal ? NetTxCalBak_calEntry_f : NetTxCal_calEntry_f;

    for(i = 0; i <= walk_end; i++)    
    {       
        entry_id = DRV_INS(dp_id, dp_txqm_id*64+i);
        cmd      = DRV_IOR(table, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, entry_id, cmd, &nettx_cal));

        val_32   = p_cal[i];
        DRV_IOW_FIELD_NZ(lchip, table, field, &val_32, &nettx_cal, dp_id, dp_txqm_id*64+i);

        cmd      = DRV_IOW(table, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, entry_id, cmd, &nettx_cal));
    }

    /* WalkerEnd */
    entry_id = DRV_INS(dp_id, 0);
    cmd      = DRV_IOR(NetTxCalCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, entry_id, cmd, &cal_ctl));
    if(is_back_cal)
    {
        dmps_NetTxCalCtl_walkerEnd0Bak_f(dp_txqm_id, field);
    }
    else
    {
        dmps_NetTxCalCtl_walkerEnd0_f(dp_txqm_id, field);
    }    
    val_32   = walk_end;
    DRV_IOW_FIELD_NZ(lchip, NetTxCalCtl_t, field, &val_32, &cal_ctl, dp_id, 0);
    
    cmd      = DRV_IOW(NetTxCalCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, entry_id, cmd, &cal_ctl));

    /* bank sel */
    entry_id = DRV_INS(dp_id, 0);
    cmd      = DRV_IOR(NetTxCalCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, entry_id, cmd, &cal_ctl));

    val_32   = is_back_cal;
    dmps_NetTxCalCtl_calEntry0Sel_f(dp_txqm_id, field);
    DRV_IOW_FIELD_NZ(lchip, NetTxCalCtl_t, field, &val_32, &cal_ctl, dp_id, 0);
    cmd      = DRV_IOW(NetTxCalCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, entry_id, cmd, &cal_ctl));

    return CTC_E_NONE;
}

int32
_sys_tmg_datapath_set_nettx_calendar(uint8 lchip, uint8 dp_id, uint32 dp_txqm_id)
{
    int32   ret                      = CTC_E_NONE;
    uint8   error                    = TRUE;
    uint16  walk_end                 = 0;
    uint16* cal                      = NULL;
    sys_cal_info_collect_t* cal_info = NULL;

    cal_info = (sys_cal_info_collect_t*)mem_malloc(MEM_DMPS_MODULE, SYS_TMG_MAC_CLIENT_NUM_PER_DP * sizeof(sys_cal_info_collect_t));
    if(NULL == cal_info)
    {
        goto RELEASE_PTR_RETURN;
    }
    cal = (uint16*)mem_malloc(MEM_DMPS_MODULE, (SYS_TMG_MAX_CAL_LEN*2) * sizeof(uint16));
    if(NULL == cal)
    {
        goto RELEASE_PTR_RETURN;
    }
    sal_memset(cal, 0, (SYS_TMG_MAX_CAL_LEN*2) * sizeof(uint16));

    CTC_ERROR_RETURN(_sys_tmg_calendar_speed_info_collect(lchip, cal_info, dp_id, dp_txqm_id, SYS_DMPS_NETTX_CAL));

    /*1. Run new calendar algorithm*/
    CTC_ERROR_GOTO(_sys_tmg_datapath_nettx_common_calendar(lchip, dp_id, dp_txqm_id, &error, &walk_end, cal, cal_info), 
        ret, RELEASE_PTR_RETURN);
    /*2. Run old algorithm if 1 fail*/
    if(error)
    {
        sal_memset(cal, 0, SYS_TMG_MAX_CAL_LEN * 2 * sizeof(uint16));
        walk_end = 0;
        CTC_ERROR_GOTO(_sys_tmg_datapath_calculate_nettx_calendar(lchip, dp_id, dp_txqm_id, cal, &walk_end, cal_info), 
            ret, RELEASE_PTR_RETURN);
    }
    /*3. Write to register*/
    if(128 > walk_end)
    {
        CTC_ERROR_GOTO(_sys_tmg_datapath_nettx_cal_cfg(lchip, dp_id, dp_txqm_id, cal, walk_end), ret, RELEASE_PTR_RETURN);
    }
    
RELEASE_PTR_RETURN:
    mem_free(cal);
    mem_free(cal_info);
    
    return ret;
}

/*DsNetRxPortToChanMap1 (dp, dp_mac_id) NW only*/
/*NETRX map mac_id to channel, NW only*/
int32
_sys_tmg_datapath_map_netrx_mac_2_chan(uint8 lchip, uint32 dp, uint32 dp_mac_id, uint32 dp_chan)
{
    uint32 cmd           = 0;
    uint32 entry         = DRV_INS(dp, dp_mac_id);
    DsNetRxPortToChanMap1_m mac_to_chan;

    SYS_CONDITION_RETURN(((dp_mac_id >= SYS_TMG_MAX_MAC_NUM_PER_DP) || (dp_chan >= SYS_TMG_CHANNEL_NUM_PER_DP)), CTC_E_NONE);

    cmd = DRV_IOR(DsNetRxPortToChanMap1_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, entry, cmd, &mac_to_chan));

    DRV_IOW_FIELD_NZ(lchip, DsNetRxPortToChanMap1_t, DsNetRxPortToChanMap1_chan_f, &dp_chan, &mac_to_chan, 
        dp, dp_mac_id);

    cmd = DRV_IOW(DsNetRxPortToChanMap1_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, entry, cmd, &mac_to_chan));
    
    return CTC_E_NONE;
}

/*DsNetRxPortToChanMap (dp, dp_mac_client) NW only*/
/*NETRX map mac-client to channel, NW only*/
int32
_sys_tmg_datapath_map_netrx_port_2_chan(uint8 lchip, uint32 dp, uint32 dp_mac_client, uint32 dp_chan)
{
    uint32 cmd           = 0;
    uint32 entry         = DRV_INS(dp, dp_mac_client);
    DsNetRxPortToChanMap_m port_to_chan;

    SYS_CONDITION_RETURN((dp_mac_client >= SYS_TMG_MAC_CLIENT_NW_NUM_PER_DP || (dp_chan >= SYS_TMG_CHANNEL_NUM_PER_DP)), CTC_E_NONE);

    cmd = DRV_IOR(DsNetRxPortToChanMap_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, entry, cmd, &port_to_chan));

    DRV_IOW_FIELD_NZ(lchip, DsNetRxPortToChanMap_t, DsNetRxPortToChanMap_chan_f, &dp_chan, &port_to_chan, 
        dp, dp_mac_client);

    cmd = DRV_IOW(DsNetRxPortToChanMap_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, entry, cmd, &port_to_chan));

    return CTC_E_NONE;
}

/*DsNetRxChanToPortMap (dp, dp_chan)*/
/*NETRX map channel to mac-client, NW only*/
int32
_sys_tmg_datapath_map_netrx_chan_2_port(uint8 lchip, uint32 dp, uint32 dp_mac_client, uint32 dp_chan)
{
    uint32 cmd        = 0;
    uint32 entry      = DRV_INS(dp, dp_chan);
    DsNetRxChanToPortMap_m chan_to_port;

    SYS_CONDITION_RETURN((dp_mac_client >= SYS_TMG_MAC_CLIENT_NW_NUM_PER_DP || (dp_chan >= SYS_TMG_CHANNEL_NUM_PER_DP)), CTC_E_NONE);

    cmd = DRV_IOR(DsNetRxChanToPortMap_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, entry, cmd, &chan_to_port));

    DRV_IOW_FIELD_NZ(lchip, DsNetRxChanToPortMap_t, DsNetRxChanToPortMap_portId_f, &dp_mac_client, &chan_to_port, 
        dp, dp_chan);

    cmd = DRV_IOW(DsNetRxChanToPortMap_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, entry, cmd, &chan_to_port));

    return CTC_E_NONE;
}

/*EpeSchedulePortToChanRa (dp, dp_mac_client)*/
/*EPE port has 89 per dp, 0~79 NW, 80~88 misc*/
int32
_sys_tmg_datapath_map_epe_port_2_chan(uint8 lchip, uint32 dp, uint32 dp_mac_client, uint32 dp_chan)
{
    uint32  index      = 0;
    uint32  cmd        = 0;
    EpeSchedulePortToChanRa_m port_to_chan = {{0}};

    SYS_CONDITION_RETURN((dp_mac_client >= SYS_TMG_EPE_PORT_PER_DP), CTC_E_NONE);

    /* port to chan mapping*/
    index = DRV_INS(dp, dp_mac_client);
    cmd = DRV_IOR(EpeSchedulePortToChanRa_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &port_to_chan));
    DRV_IOW_FIELD_NZ(lchip, EpeSchedulePortToChanRa_t, EpeSchedulePortToChanRa_internalChanId_f,
        &dp_chan, &port_to_chan, dp, dp_mac_client);
    cmd = DRV_IOW(EpeSchedulePortToChanRa_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &port_to_chan));

    return CTC_E_NONE;
}

/*EpeScheduleChanToPortRa (dp, dp_chan)*/
/*EPE chan has 64 per dp, NW & misc*/
int32
_sys_tmg_datapath_map_epe_chan_2_port(uint8 lchip, uint32 dp, uint32 dp_mac_client, uint32 dp_chan)
{
    uint32  index      = 0;
    uint32  cmd        = 0;
    EpeScheduleChanToPortRa_m chan_to_port = {{0}};

    /* chan to port mapping*/
    index = DRV_INS(dp, dp_chan);
    cmd = DRV_IOR(EpeScheduleChanToPortRa_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &chan_to_port));
    DRV_IOW_FIELD_NZ(lchip, EpeScheduleChanToPortRa_t, EpeScheduleChanToPortRa_physicalPortId_f,
        &dp_mac_client, &chan_to_port, dp, dp_chan);
    cmd = DRV_IOW(EpeScheduleChanToPortRa_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &chan_to_port));

    return CTC_E_NONE;
}

/*IpeHeaderAdjustPhyPortMap (0, chan256)*/
int32
_sys_tmg_datapath_map_ipe_chan_2_lport(uint8 lchip, uint32 dport, uint32 chan)
{
    uint32 cmd = 0;
    IpeHeaderAdjustPhyPortMap_m  ipe_map;

    cmd = DRV_IOR(IpeHeaderAdjustPhyPortMap_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, chan, cmd, &ipe_map));

    DRV_IOW_FIELD_NZ(lchip, IpeHeaderAdjustPhyPortMap_t, IpeHeaderAdjustPhyPortMap_localPhyPort_f, 
        &dport, &ipe_map, 0, chan);

    cmd = DRV_IOW(IpeHeaderAdjustPhyPortMap_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, chan, cmd, &ipe_map));

    return CTC_E_NONE;
}

/*EpeHeaderAdjustPhyPortMap (0, chan256)*/
int32
_sys_tmg_datapath_map_epe_chan_2_lport(uint8 lchip, uint32 dport, uint32 chan)
{
    uint32 cmd = 0;
    EpeHeaderAdjustPhyPortMap_m  epe_map;

    cmd = DRV_IOR(EpeHeaderAdjustPhyPortMap_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, chan, cmd, &epe_map));

    DRV_IOW_FIELD_NZ(lchip, EpeHeaderAdjustPhyPortMap_t, EpeHeaderAdjustPhyPortMap_localPhyPort_f, 
        &dport, &epe_map, 0, chan);

    cmd = DRV_IOW(EpeHeaderAdjustPhyPortMap_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, chan, cmd, &epe_map));

    return CTC_E_NONE;
}

int32
_sys_tmg_datapath_set_map_by_chan(uint8 lchip, uint8 dp, uint16 dp_chan, uint8 dir)
{
    uint16 dport      = 0;
    uint16 chan_id    = 0;
    uint16 mac_client = 0;
    uint16 mac_id     = 0;
    uint16 port_type  = 0;
    sys_dmps_db_upt_info_t port_info = {0};
    sys_dmps_db_chan_info_t chan_info = {0};

    chan_id = SYS_TMG_DPCHAN_TO_CHANNEL(dp_chan, dp);

    /*NW & MISC*/
    /*tx*/
    if (CHAN_DIR_IS_TX(dir))
    {
        SYS_CONDITION_RETURN(FALSE == sys_usw_dmps_db_is_valid_id(lchip, GET_CHAN_TYPE_BY_DIR(CHAN_DIR_TX), chan_id), CTC_E_NONE);

        CTC_ERROR_RETURN(sys_usw_dmps_db_get_chan_info(lchip, &chan_info, CHAN_DIR_TX));
        if (SYS_DMPS_INVALID_SUB_CHAN_ID == chan_info.sub_chan_id)
        {
            return CTC_E_NONE;
        }

        CTC_ERROR_RETURN(sys_usw_dmps_db_upt_info_init(lchip, &port_info));
        DMPS_DB_SET_MAP_INFO(port_info, GET_CHAN_ID_BY_DIR(CHAN_DIR_TX), chan_id);
        DMPS_DB_SET_PROPERTY_UPDATE(port_info, DMPS_DB_CHAN_MAC_CLIENT_ID);
        CTC_ERROR_RETURN(sys_usw_dmps_db_get_port_info(lchip, &port_info));
        DMPS_DB_GET_MAP_INFO(port_info, DMPS_DB_DPORT, dport);
        DMPS_DB_GET_PROPERTY_INFO(port_info, DMPS_DB_CHAN_MAC_CLIENT_ID, mac_client);

        CTC_ERROR_RETURN(_sys_tmg_datapath_map_epe_port_2_chan(lchip, dp, mac_client, dp_chan));
        CTC_ERROR_RETURN(_sys_tmg_datapath_map_epe_chan_2_port(lchip, dp, mac_client, dp_chan));
        if(DMPS_INVALID_VALUE_U16 != dport)
        {
            CTC_ERROR_RETURN(_sys_tmg_datapath_map_epe_chan_2_lport(lchip, dport, SYS_TMG_CHANNEL_TO_256CHAN(chan_id)));
        }
    }
    
    /*rx*/
    if (CHAN_DIR_IS_RX(dir))
    {
        SYS_CONDITION_RETURN(FALSE == sys_usw_dmps_db_is_valid_id(lchip, GET_CHAN_TYPE_BY_DIR(CHAN_DIR_RX), chan_id), CTC_E_NONE);

        CTC_ERROR_RETURN(sys_usw_dmps_db_get_chan_info(lchip, &chan_info, CHAN_DIR_RX));
        if (SYS_DMPS_INVALID_SUB_CHAN_ID == chan_info.sub_chan_id)
        {
            return CTC_E_NONE;
        }

        CTC_ERROR_RETURN(sys_usw_dmps_db_upt_info_init(lchip, &port_info));
        DMPS_DB_SET_MAP_INFO(port_info, GET_CHAN_ID_BY_DIR(CHAN_DIR_RX), chan_id);
        DMPS_DB_SET_PROPERTY_UPDATE(port_info, DMPS_DB_CHAN_RX_MAC_CLIENT_ID);
        DMPS_DB_SET_PROPERTY_UPDATE(port_info, DMPS_DB_PORT_TYPE);
        CTC_ERROR_RETURN(sys_usw_dmps_db_get_port_info(lchip, &port_info));
        DMPS_DB_GET_MAP_INFO(port_info, DMPS_DB_DPORT, dport);
        DMPS_DB_GET_MAP_INFO(port_info, DMPS_DB_MAC_ID, mac_id);
        DMPS_DB_GET_PROPERTY_INFO(port_info, DMPS_DB_CHAN_RX_MAC_CLIENT_ID, mac_client);
        DMPS_DB_GET_PROPERTY_INFO(port_info, DMPS_DB_PORT_TYPE,             port_type);

        CTC_ERROR_RETURN(_sys_tmg_datapath_map_netrx_port_2_chan(lchip, dp, mac_client, dp_chan));
        CTC_ERROR_RETURN(_sys_tmg_datapath_map_netrx_chan_2_port(lchip, dp, mac_client, dp_chan));
        if((DMPS_INVALID_VALUE_U16 != mac_id) && (!SYS_USW_IS_CPUMAC_PORT(port_type)))
        {
            CTC_ERROR_RETURN(_sys_tmg_datapath_map_netrx_mac_2_chan(lchip, dp, SYS_TMG_GET_DP_MAC_ID(mac_id), dp_chan));
        }
        if(DMPS_INVALID_VALUE_U16 != dport)
        {
            CTC_ERROR_RETURN(_sys_tmg_datapath_map_ipe_chan_2_lport(lchip, dport, SYS_TMG_CHANNEL_TO_256CHAN(chan_id)));
        }

    }

    return CTC_E_NONE;
}

int32
_sys_tmg_datapath_set_dp_map(uint8 lchip, uint8 dp)
{
    uint16 dp_chan    = 0;

    /*NW & MISC*/
    /*tx*/
    for(dp_chan = 0; dp_chan < SYS_TMG_CHANNEL_NUM_PER_DP; dp_chan++)
    {
        CTC_ERROR_RETURN(_sys_tmg_datapath_set_map_by_chan(lchip, dp, dp_chan, CHAN_DIR_TX));
    }
    
    /*rx*/
    for(dp_chan = 0; dp_chan < SYS_TMG_CHANNEL_NUM_PER_DP; dp_chan++)
    {
        CTC_ERROR_RETURN(_sys_tmg_datapath_set_map_by_chan(lchip, dp, dp_chan, CHAN_DIR_RX));
    }

    return CTC_E_NONE;
}

/*NetRxWrrWeight (dp, 0)*/
/*DsNetRxPortWeightCfg (dp, dp_mac_client)*/
/*DsNetRxBufAdmissionCtl (dp, dp_mac_client)*/
/*NetRxBufManagement (dp, 0)*/
int32
_sys_tmg_datapath_set_dp_netrx_cfg(uint8 lchip, uint8 dp)
{
    const uint32 low_threshold_pre = 360;
    const uint32 low_threshold_adj = 2;
    uint8  speed_mode              = 0;
    uint8  port_type               = 0;
    uint8  txqm                    = 0;
    uint16 dp_mac_client           = 0;
    uint16 dp_chan                 = 0;
    uint16 chan_id                 = 0;
    uint16 dp_txqm                 = 0;
    uint16 txqm_mac_client         = 0;
    uint32 entry                   = 0;
    uint32 val_32                  = 0;
    uint32 cmd                     = 0;
    uint32 fld_id                  = 0;
    uint32 guarantee_depth         = 0; //value * factor
    uint32 speed                   = 0;
    uint16 mac_client              = 0;
    uint32 txqm_bw_max             = 0;
    uint32 mid_threshold_adj       = 0;
    uint32 low_thrd_final          = 0;
    uint32 mid_thrd_final          = 0;
    uint16 weight                  = 0;
    uint16 divisor                 = 0;
    uint16 txqm_div                = 0;
    uint32 opt_weight              = 0;
    uint16 txqm_weight[SYS_TMG_TXQM_NUM_PER_DP][SYS_TMG_MAC_CLIENT_NUM_PER_TXQM] = {{0}};
    uint16 weight_arr[SYS_TMG_TXQM_NUM_PER_DP] = {0};
    uint32 txqms_bandwith[SYS_TMG_TXQM_NUM_PER_DP]     = {0};
    uint32 guarantee_depth_ge[SYS_TMG_TXQM_NUM_PER_DP] = {0};
    uint32 guarantee_depth_xg[SYS_TMG_TXQM_NUM_PER_DP] = {0};
    uint32 low_threshold[SYS_TMG_TXQM_NUM_PER_DP]      = {0};
    uint16 port_speed[SYS_TMG_TXQM_NUM_PER_DP][SYS_TMG_MAC_CLIENT_NUM_PER_TXQM] = {{0}};
    sys_dmps_db_upt_info_t port_info = {0};
    NetRxBufManagement_m     buf_mng;
    DsNetRxBufAdmissionCtl_m buf_adm;
    NetRxWrrWeight_m         wrr_cfg;
    DsNetRxPortWeightCfg_m   wgt_cfg;

    /*0. calculate all txqms bw sum in this DP, NW only, considering XPIPE*/
    for(dp_chan = 0; dp_chan < SYS_TMG_CHANNEL_NUM_PER_DP; dp_chan++)
    {
        chan_id = SYS_TMG_DPCHAN_TO_CHANNEL(dp_chan, dp);
        SYS_CONDITION_CONTINUE(FALSE == sys_usw_dmps_db_is_valid_id(lchip, DMPS_DB_TYPE_CHAN_RX, chan_id));

        CTC_ERROR_RETURN(sys_usw_dmps_db_upt_info_init(lchip, &port_info));
        DMPS_DB_SET_MAP_INFO(port_info, DMPS_DB_CHAN_RX_ID, chan_id);
        DMPS_DB_SET_PROPERTY_UPDATE(port_info, DMPS_DB_PORT_TYPE);
        DMPS_DB_SET_PROPERTY_UPDATE(port_info, DMPS_DB_CHAN_RX_SPEED_MODE);
        DMPS_DB_SET_PROPERTY_UPDATE(port_info, DMPS_DB_CHAN_TXQM_ID);
        DMPS_DB_SET_PROPERTY_UPDATE(port_info, DMPS_DB_CHAN_MAC_CLIENT_ID);
        CTC_ERROR_RETURN(sys_usw_dmps_db_get_port_info(lchip, &port_info));
        DMPS_DB_GET_PROPERTY_INFO(port_info, DMPS_DB_PORT_TYPE,          port_type);
        DMPS_DB_GET_PROPERTY_INFO(port_info, DMPS_DB_CHAN_RX_SPEED_MODE, speed_mode);
        DMPS_DB_GET_PROPERTY_INFO(port_info, DMPS_DB_CHAN_TXQM_ID,       txqm);
        DMPS_DB_GET_PROPERTY_INFO(port_info, DMPS_DB_CHAN_MAC_CLIENT_ID, mac_client);

        SYS_CONDITION_CONTINUE(SYS_DMPS_NETWORK_PORT != port_type);
        dp_txqm = SYS_TMG_GET_DP_TXQM_BY_TXQM(txqm);
        txqm_mac_client = SYS_TMG_GET_TXQM_MAC_CLIENT(mac_client);
        SYS_DATAPATH_MODE_TO_SPEED(speed_mode, speed);
        SYS_DATAPATH_SPEED_TO_WRRCFG(speed_mode, weight);
        port_speed[dp_txqm][txqm_mac_client] = speed;
        txqms_bandwith[dp_txqm] += speed;
        txqm_weight[dp_txqm][txqm_mac_client] = weight;
        weight_arr[dp_txqm] += weight;
    }
    for(dp_txqm = 0; dp_txqm < SYS_TMG_TXQM_NUM_PER_DP; dp_txqm++)
    {
        if(txqm_bw_max < txqms_bandwith[dp_txqm])
        {
            txqm_bw_max = txqms_bandwith[dp_txqm];
        }
    }
    SYS_CONDITION_RETURN((0 == txqm_bw_max), CTC_E_NONE);

    CTC_ERROR_RETURN(sys_usw_datapath_get_gcd(weight_arr, SYS_TMG_TXQM_NUM_PER_DP, &divisor));

    /*1. set NetRxWrrWeight */
    entry = DRV_INS(dp, 0);
    cmd = DRV_IOR(NetRxWrrWeight_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, entry, cmd, &wrr_cfg));
    for(dp_txqm = 0; dp_txqm < SYS_TMG_TXQM_NUM_PER_DP; dp_txqm++)
    {
        opt_weight = weight_arr[dp_txqm] / divisor;
        dmps_NetRxWrrWeight_cfgNetWorkWeight0_f(dp_txqm, fld_id);
        DRV_IOW_FIELD_NZ(lchip, NetRxWrrWeight_t, fld_id, &opt_weight, &wrr_cfg, dp, 0);
    }
    cmd = DRV_IOW(NetRxWrrWeight_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, entry, cmd, &wrr_cfg));
    for(dp_txqm = 0; dp_txqm < SYS_TMG_TXQM_NUM_PER_DP; dp_txqm++)
    {
        guarantee_depth_ge[dp_txqm] = low_threshold_pre / txqm_bw_max;
        guarantee_depth_xg[dp_txqm] = low_threshold_pre * 10 / txqm_bw_max;
        /*compensation factor for cg/lg/xxvg*/
        divisor = (400 == txqms_bandwith[dp_txqm] ? 5 : 6);

        CTC_ERROR_RETURN(sys_usw_datapath_get_gcd(txqm_weight[dp_txqm], SYS_TMG_MAC_CLIENT_NUM_PER_TXQM, &txqm_div));

        for(txqm_mac_client = 0; txqm_mac_client < SYS_TMG_MAC_CLIENT_NUM_PER_TXQM; txqm_mac_client++)
        {
            speed = port_speed[dp_txqm][txqm_mac_client];
            SYS_CONDITION_CONTINUE(0 == speed);

            dp_mac_client = dp_txqm*SYS_TMG_MAC_CLIENT_NUM_PER_TXQM + txqm_mac_client;

            /*2. set DsNetRxPortWeightCfg*/
            entry = DRV_INS(dp, dp_mac_client);
            cmd = DRV_IOR(DsNetRxPortWeightCfg_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, entry, cmd, &wgt_cfg));
            opt_weight = txqm_weight[dp_txqm][txqm_mac_client] / txqm_div;
            DRV_IOW_FIELD_NZ(lchip, DsNetRxPortWeightCfg_t, DsNetRxPortWeightCfg_weight_f,
                    &opt_weight, &wgt_cfg, dp, dp_mac_client);
            cmd = DRV_IOW(DsNetRxPortWeightCfg_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, entry, cmd, &wgt_cfg));

            /*3. set DsNetRxBufAdmissionCtl*/
            /*10G/25G/../400G*/
            if(speed >= 10)
            {
                guarantee_depth = (SYS_SCALE_FACTOR * speed * guarantee_depth_xg[dp_txqm]) / 10;
                if(speed > 10)
                {
                    guarantee_depth -= ((SYS_SCALE_FACTOR * guarantee_depth_xg[dp_txqm]) / divisor);
                }
            }
            /*1G/5G*/
            else
            {
                guarantee_depth = SYS_SCALE_FACTOR * speed * guarantee_depth_ge[dp_txqm];
            }
            entry = DRV_INS(dp, dp_mac_client);
            val_32 = guarantee_depth / SYS_SCALE_FACTOR;
            cmd = DRV_IOR(DsNetRxBufAdmissionCtl_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, entry, cmd, &buf_adm));
            DRV_IOW_FIELD_NZ(lchip, DsNetRxBufAdmissionCtl_t, DsNetRxBufAdmissionCtl_cfgGuaranteeBufferNum_f, 
                &val_32, &buf_adm, dp, dp_mac_client);
            cmd = DRV_IOW(DsNetRxBufAdmissionCtl_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, entry, cmd, &buf_adm));

            low_threshold[dp_txqm] += guarantee_depth;
        }
        
        /*4. set NetRxBufManagement*/
        /*little_data ignored*/
        low_threshold[dp_txqm] = (100 * SYS_SCALE_FACTOR > low_threshold[dp_txqm]) ? 
            100 * SYS_SCALE_FACTOR : low_threshold[dp_txqm];
        mid_threshold_adj = 80 * txqms_bandwith[dp_txqm] / txqm_bw_max;

        low_thrd_final = low_threshold[dp_txqm] / SYS_SCALE_FACTOR + low_threshold_adj;
        mid_thrd_final = low_thrd_final + mid_threshold_adj;

        entry = DRV_INS(dp, 0);
        cmd = DRV_IOR(NetRxBufManagement_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, entry, cmd, &buf_mng));
        val_32 = low_thrd_final;
        DRV_IOW_FIELD_NZ(lchip, NetRxBufManagement_t, NetRxBufManagement_cfgLowThrd0_f + dp_txqm, 
            &val_32, &buf_mng, dp, 0);
        val_32 = mid_thrd_final;
        DRV_IOW_FIELD_NZ(lchip, NetRxBufManagement_t, NetRxBufManagement_cfgMidThrd0_f + dp_txqm, 
            &val_32, &buf_mng, dp, 0);
        cmd = DRV_IOW(NetRxBufManagement_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, entry, cmd, &buf_mng));
    }

    return CTC_E_NONE;
}

int32
_sys_tmg_datapath_bufretrv_get_credit(uint8 lchip, uint16 speed, sys_datapath_bufsz_step_t *step)
{
    uint8  i       = 0;
    const uint16 speed_num = 8;
    const uint16 speed_lines[] = {0, 9, 10, 25, 40, 50, 100, 200};    // sizeof speed_lines must be speed_num
    const uint16 credits[][3] = {   /*br_credit, sop buf, body buf, speed*/
                                     {0,         0,       0 },   /*MAX*/
                                     {2,         4,       3 },   /*<10G*/
                                     {3,         6,       3 },   /*10G*/
                                     {3,         13,      9 },   /*25G*/
                                     {5,         21,      15},   /*40G*/
                                     {6,         26,      19},   /*50G*/
                                     {12,        52,      33},   /*100G*/
                                     {24,        96,      60}};  /*200G*/


    while((i < speed_num) && (speed > speed_lines[i]))
    {
        i++;
    }

    SYS_CONDITION_RETURN((i >= speed_num), CTC_E_INVALID_PARAM);

    step->br_credit_cfg = credits[i][0];
    step->sop_buf_num = credits[i][1];
    step->body_buf_num = credits[i][2];

    return CTC_E_NONE;
}

/*BufRetrvDPCreditConfigMem (dp, dp_chan)*/
/*BufRetrvDPBufCredit (dp, dp_chan)*/
int32
_sys_tmg_datapath_set_bufretrv_credit(uint8 lchip, uint8 dp, uint16 dp_chan, uint8 speed_mode)
{
    uint16   speed      = 0;
    uint32   cmd        = 0;
    uint32   tmp_val32  = 0;
    uint32   entry_id   = 0;
    BufRetrvDPBufCredit_m        buf_credit;
    BufRetrvDPCreditConfigMem_m  body_sop_credit;
    sys_datapath_bufsz_step_t    step = {0};

    entry_id = DRV_INS(dp, dp_chan);

    SYS_DATAPATH_MODE_TO_SPEED(speed_mode, speed);
    CTC_ERROR_RETURN(_sys_tmg_datapath_bufretrv_get_credit(lchip, speed, &step));

    /*Buf Credit*/
    cmd = DRV_IOR(BufRetrvDPBufCredit_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, entry_id, cmd, &buf_credit));

    tmp_val32 = step.br_credit_cfg;
    DRV_IOW_FIELD_NZ(lchip, BufRetrvDPBufCredit_t, BufRetrvDPBufCredit_bufCredit_f, &tmp_val32, &buf_credit,
        dp, dp_chan);

    cmd = DRV_IOW(BufRetrvDPBufCredit_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, entry_id, cmd, &buf_credit));


    /*Body Credit*/
    cmd = DRV_IOR(BufRetrvDPCreditConfigMem_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, entry_id, cmd, &body_sop_credit));

    tmp_val32 = step.sop_buf_num;
    DRV_IOW_FIELD_NZ(lchip, BufRetrvDPCreditConfigMem_t, BufRetrvDPCreditConfigMem_sopCreditCfg_f, &tmp_val32, &body_sop_credit,
        dp, dp_chan);
    /*Sop Credit */
    tmp_val32= step.body_buf_num;
    DRV_IOW_FIELD_NZ(lchip, BufRetrvDPCreditConfigMem_t, BufRetrvDPCreditConfigMem_bodyCreditCfg_f, &tmp_val32, &body_sop_credit,
        dp, dp_chan);

    cmd = DRV_IOW(BufRetrvDPCreditConfigMem_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, entry_id, cmd, &body_sop_credit));

    return CTC_E_NONE;
}

/*Get virtual txqm id by dp_chan_id.
Virtual txqm id is NOT mac txqm id. It is used for ASIC internal algorithms.
Mac-Chan mapping will not influence virtual txqm id.
It divides channel id in one DP into 7 parts based on dp_chan_id value range:

dp_chan_id | vtxqm   | vtxqm_chan
-----------+---------------
 0 ~ 7     | 0       | 0~7
 8 ~ 15    | 1       | 0~7
 16~ 23    | 2       | 0~7
 24~ 31    | 3       | 0~7
 32~ 39    | 4       | 0~7
 40~ 47    | 5       | 0~7
 48~ 63    | 6(misc) | 0~15
*/
int32
_sys_tmg_datapath_get_virtual_txqm_chan(uint16 dp_chan_id, uint8* p_vtxqm, uint8* p_vtxqm_chan)
{
    SYS_CONDITION_RETURN((SYS_TMG_CHANNEL_NUM_PER_DP <= dp_chan_id), CTC_E_INVALID_PARAM);

    if(47 < dp_chan_id)
    {
        SYS_USW_VALID_PTR_WRITE(p_vtxqm,      6);
        SYS_USW_VALID_PTR_WRITE(p_vtxqm_chan, (dp_chan_id % 16));
    }
    else
    {
        SYS_USW_VALID_PTR_WRITE(p_vtxqm,      (dp_chan_id / 8));
        SYS_USW_VALID_PTR_WRITE(p_vtxqm_chan, (dp_chan_id % 8));
    }

    return CTC_E_NONE;
}

/*config virtual txqm id related chan enable*/
STATIC int32
_sys_tmg_datapath_set_virtual_txqm_en(uint8 lchip, uint8 dp)
{
    uint32 cmd       = 0;
    uint32 entry_id  = 0;
    uint32 en_bmp    = 0xff;
    BufRetrvDPWrrCtl_m wrr_ctl;

    entry_id = DRV_INS(dp, 0);
    cmd = DRV_IOR(BufRetrvDPWrrCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, entry_id, cmd, &wrr_ctl));

    DRV_IOW_FIELD_NZ(lchip, BufRetrvDPWrrCtl_t, BufRetrvDPWrrCtl_txqm0ReqEn_f, &en_bmp, &wrr_ctl, dp, 0);
    DRV_IOW_FIELD_NZ(lchip, BufRetrvDPWrrCtl_t, BufRetrvDPWrrCtl_txqm1ReqEn_f, &en_bmp, &wrr_ctl, dp, 0);
    DRV_IOW_FIELD_NZ(lchip, BufRetrvDPWrrCtl_t, BufRetrvDPWrrCtl_txqm2ReqEn_f, &en_bmp, &wrr_ctl, dp, 0);
    DRV_IOW_FIELD_NZ(lchip, BufRetrvDPWrrCtl_t, BufRetrvDPWrrCtl_txqm3ReqEn_f, &en_bmp, &wrr_ctl, dp, 0);
    DRV_IOW_FIELD_NZ(lchip, BufRetrvDPWrrCtl_t, BufRetrvDPWrrCtl_txqm4ReqEn_f, &en_bmp, &wrr_ctl, dp, 0);
    DRV_IOW_FIELD_NZ(lchip, BufRetrvDPWrrCtl_t, BufRetrvDPWrrCtl_txqm5ReqEn_f, &en_bmp, &wrr_ctl, dp, 0);
    en_bmp = 0xffff;
    DRV_IOW_FIELD_NZ(lchip, BufRetrvDPWrrCtl_t, BufRetrvDPWrrCtl_miscGroupReqEn_f, &en_bmp, &wrr_ctl, dp, 0);

    cmd = DRV_IOW(BufRetrvDPWrrCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, entry_id, cmd, &wrr_ctl));

    return CTC_E_NONE;
}

/*BR weight divided in vtxqm group*/
uint32
_sys_tmg_datapath_get_br_wt_sub_divisor(uint16* weight_arr, uint16 opt_wt[])
{
    uint16 dp_chan;
    uint8  vtxqm;
    uint8  vtxqm_chan;
    uint16 count;
    uint16 weight_of_txqms[7][16] = {{0}};  //index [virtual txqm id][chan id in single virtual txqm id]
    uint16 divisors[7] = {0};

    for(dp_chan = 0; dp_chan < SYS_TMG_CHANNEL_NUM_PER_DP; dp_chan++)
    {
        CTC_ERROR_RETURN(_sys_tmg_datapath_get_virtual_txqm_chan(dp_chan, &vtxqm, &vtxqm_chan));
        weight_of_txqms[vtxqm][vtxqm_chan] = weight_arr[dp_chan];
    }

    for(vtxqm = 0; vtxqm < 7; vtxqm++)
    {
        count = (6 == vtxqm) ? 16 : 8;
        CTC_ERROR_RETURN(sys_usw_datapath_get_gcd((uint16*)(weight_of_txqms[vtxqm]), count,  &(divisors[vtxqm])));
    }

    for(dp_chan = 0; dp_chan < SYS_TMG_CHANNEL_NUM_PER_DP; dp_chan++)
    {
        CTC_ERROR_RETURN(_sys_tmg_datapath_get_virtual_txqm_chan(dp_chan, &vtxqm, &vtxqm_chan));
        opt_wt[dp_chan] = weight_of_txqms[vtxqm][vtxqm_chan] / divisors[vtxqm];
    }

    return CTC_E_NONE;
}

/*set EpeWfCfgMem and PkfWFCfgMem origin weight*/
/*BufRetrvDPEpeWtCfgMem (dp, dp_chan_id)*/
/*BufRetrvDPPktWtCfgMem (dp, dp_chan_id)*/
uint32
_sys_tmg_datapath_bufretrv_weight_cfg(uint8 lchip, uint16* weight_arr, uint8 dp)
{
    uint8  dp_chan_id;
    uint32 opt_weight     = 0;
    uint32 cmd            = 0;
    uint32 entry_id       = 0;
    uint16 opt_wt[SYS_TMG_CHANNEL_NUM_PER_DP] = {0};
    BufRetrvDPEpeWtCfgMem_m epe_weight_cfg;
    BufRetrvDPPktWtCfgMem_m pkt_weight_cfg;

    CTC_ERROR_RETURN(_sys_tmg_datapath_get_br_wt_sub_divisor(weight_arr, opt_wt));

    for(dp_chan_id = 0; dp_chan_id < SYS_TMG_CHANNEL_NUM_PER_DP; dp_chan_id++)
    {
        entry_id = DRV_INS(dp, dp_chan_id);
        opt_weight = (opt_wt[dp_chan_id] == 0) ? 1 : opt_wt[dp_chan_id];

        /* BufRetrvDPEpeWfCfgMem */
        cmd = DRV_IOR(BufRetrvDPEpeWtCfgMem_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, entry_id, cmd, &epe_weight_cfg));

        DRV_IOW_FIELD_NZ(lchip, BufRetrvDPEpeWtCfgMem_t, BufRetrvDPEpeWtCfgMem_weight_f,
            &opt_weight, &epe_weight_cfg, dp, dp_chan_id);
        cmd = DRV_IOW(BufRetrvDPEpeWtCfgMem_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, entry_id, cmd, &epe_weight_cfg));

        /* BufRetrvDPPktWfCfgMem */
        cmd = DRV_IOR(BufRetrvDPPktWtCfgMem_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, entry_id, cmd, &pkt_weight_cfg));

        DRV_IOW_FIELD_NZ(lchip, BufRetrvDPPktWtCfgMem_t, BufRetrvDPPktWtCfgMem_weight_f,
            &opt_weight, &pkt_weight_cfg, dp, dp_chan_id);
        cmd = DRV_IOW(BufRetrvDPPktWtCfgMem_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, entry_id, cmd, &pkt_weight_cfg));
    }

    return CTC_E_NONE;
}

uint32
_sys_tmg_datapath_bufretrv_wrr_cfg(uint8 lchip, uint16 weight_sum[], uint8 dp)
{
    uint32 entry_id = 0;
    uint32 cmd = 0;
    uint32 fld_id = 0;
    uint16 divisor = 0;
    uint32 opt_weight = 0;
    uint8  dp_txqm_id;
    BufRetrvDPWrrCtl_m wrr_ctl;

    entry_id = DRV_INS(dp, 0);
    CTC_ERROR_RETURN(sys_usw_datapath_get_gcd(weight_sum, 7, &divisor));

    /*network*/
    cmd = DRV_IOR(BufRetrvDPWrrCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, entry_id, cmd, &wrr_ctl));

    for(dp_txqm_id = 0; dp_txqm_id < 6; dp_txqm_id++)
    {
        opt_weight = weight_sum[dp_txqm_id] / divisor;
        dmps_BufRetrvDPWrrCtl_txqm0WtCfg_f(dp_txqm_id, fld_id);
        DRV_IOW_FIELD_NZ(lchip, BufRetrvDPWrrCtl_t, fld_id, &opt_weight, &wrr_ctl, dp, 0);
    }

    /*misc*/
    opt_weight = weight_sum[6] / divisor;
    DRV_IOW_FIELD_NZ(lchip, BufRetrvDPWrrCtl_t, BufRetrvDPWrrCtl_miscGroupWtCfg_f,
        &opt_weight, &wrr_ctl, dp, 0);

    cmd = DRV_IOW(BufRetrvDPWrrCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, entry_id, cmd, &wrr_ctl));

    return CTC_E_NONE;
}

/*Here vtxqm means Virtual txqm id. It is NOT mac txqm id. It is used for ASIC internal algorithms.
Mac-Chan mapping will not influence virtual txqm id.*/
STATIC int32
_sys_tmg_datapath_set_bufretrv_wrr_weight(uint8 lchip, uint8 dp)
{
    uint8  vtxqm         = 0;
    uint8  vxtqm_chan    = 0;
    uint16 chan_id       = 0;
    uint16 dp_chan       = 0;
    uint16 wrrbase       = 0;
    uint8  speed_mode    = 0;
    uint8  port_type     = 0;
    uint8  p_chan_num    = 0;
    uint16 dport         = 0;
    uint32 xpipe_en      = 0;
    uint16 weight_sum[7] = {0};    /* DP vtxqm:0 1 2 3 4 5; misc: 6 */
    uint16 weight_arr[SYS_TMG_CHANNEL_NUM_PER_DP] = {0};
    uint16 p_chan_id[DMPS_MAX_NUM_PER_MODULE]     = {0};
    sys_dmps_db_upt_info_t port_info = {0};

    CTC_ERROR_RETURN(_sys_tmg_datapath_set_virtual_txqm_en(lchip, dp));

    /* get net channel info */
    for(dp_chan = 0; dp_chan < SYS_TMG_CHANNEL_NUM_PER_DP; dp_chan++)
    {
        chan_id = SYS_TMG_DPCHAN_TO_CHANNEL(dp_chan, dp);
        SYS_CONDITION_CONTINUE(FALSE == sys_usw_dmps_db_is_valid_id(lchip, GET_CHAN_TYPE_BY_DIR(CHAN_DIR_TX), chan_id));
        
        CTC_ERROR_RETURN(sys_usw_dmps_db_upt_info_init(lchip, &port_info));
        DMPS_DB_SET_MAP_INFO(port_info, GET_CHAN_ID_BY_DIR(CHAN_DIR_TX), chan_id);
        DMPS_DB_SET_PROPERTY_UPDATE(port_info, DMPS_DB_PORT_TYPE);
        DMPS_DB_SET_PROPERTY_UPDATE(port_info, DMPS_DB_PORT_XPIPE_EN);
        DMPS_DB_SET_PROPERTY_UPDATE(port_info, DMPS_DB_CHAN_SPEED_MODE);
        CTC_ERROR_RETURN(sys_usw_dmps_db_get_port_info(lchip, &port_info));
        DMPS_DB_GET_MAP_INFO(port_info, DMPS_DB_DPORT,                dport);
        DMPS_DB_GET_PROPERTY_INFO(port_info, DMPS_DB_PORT_TYPE,       port_type);
        DMPS_DB_GET_PROPERTY_INFO(port_info, DMPS_DB_PORT_XPIPE_EN,   xpipe_en);
        DMPS_DB_GET_PROPERTY_INFO(port_info, DMPS_DB_CHAN_SPEED_MODE, speed_mode);

        SYS_CONDITION_CONTINUE((port_type == SYS_DMPS_RSV_PORT) || (port_type == SYS_DMPS_INACTIVE_NETWORK_PORT) || 
            (CTC_PORT_SPEED_MAX <= speed_mode));
        
        /*xpipe check*/
        if(xpipe_en)
        {
            CTC_ERROR_RETURN(sys_usw_dmps_db_get_relative_id(lchip, DMPS_DB_TYPE_PORT, dport, 
                GET_CHAN_TYPE_BY_DIR(CHAN_DIR_TX), &p_chan_num, p_chan_id));
            SYS_CONDITION_CONTINUE(chan_id != p_chan_id[p_chan_num - 1]);
        }

        wrrbase = 0;
        SYS_DATAPATH_SPEED_TO_WRRCFG(speed_mode, wrrbase);
        SYS_CONDITION_CONTINUE(CTC_E_NONE != _sys_tmg_datapath_get_virtual_txqm_chan(dp_chan, &vtxqm, &vxtqm_chan));
        weight_sum[vtxqm]     += wrrbase;
        weight_arr[dp_chan] = wrrbase;
    }

    /*write tables*/
    CTC_ERROR_RETURN(_sys_tmg_datapath_bufretrv_weight_cfg(lchip, weight_arr, dp));
    /* txqm0..6ReqEn  including network & misc*/
    CTC_ERROR_RETURN(_sys_tmg_datapath_bufretrv_wrr_cfg(lchip, weight_sum, dp));

    return CTC_E_NONE;
}

STATIC int32
_sys_tmg_datapath_bufretrv_init(uint8 lchip, uint8 dp)
{
    uint16 dp_chan    = 0;
    uint16 chan_id    = 0;
    uint8  speed_mode = 0;
    uint8  port_type  = 0;
    sys_dmps_db_upt_info_t port_info = {0};

    for(dp_chan = 0; dp_chan < SYS_TMG_CHANNEL_NUM_PER_DP; dp_chan++)
    {
        chan_id = SYS_TMG_DPCHAN_TO_CHANNEL(dp_chan, dp);
        SYS_CONDITION_CONTINUE(FALSE == sys_usw_dmps_db_is_valid_id(lchip, GET_CHAN_TYPE_BY_DIR(CHAN_DIR_TX), chan_id));
        
        CTC_ERROR_RETURN(sys_usw_dmps_db_upt_info_init(lchip, &port_info));
        DMPS_DB_SET_MAP_INFO(port_info, GET_CHAN_ID_BY_DIR(CHAN_DIR_TX), chan_id);
        DMPS_DB_SET_PROPERTY_UPDATE(port_info, DMPS_DB_PORT_TYPE);
        DMPS_DB_SET_PROPERTY_UPDATE(port_info, DMPS_DB_CHAN_SPEED_MODE);
        CTC_ERROR_RETURN(sys_usw_dmps_db_get_port_info(lchip, &port_info));
        DMPS_DB_GET_PROPERTY_INFO(port_info, DMPS_DB_PORT_TYPE,       port_type);
        DMPS_DB_GET_PROPERTY_INFO(port_info, DMPS_DB_CHAN_SPEED_MODE, speed_mode);

        /* NW & MISC */
        SYS_CONDITION_CONTINUE(port_type == SYS_DMPS_RSV_PORT);

        CTC_ERROR_RETURN(_sys_tmg_datapath_set_bufretrv_credit(lchip, dp, dp_chan, speed_mode));
    }

    CTC_ERROR_RETURN(_sys_tmg_datapath_set_bufretrv_wrr_weight(lchip, dp));

    return CTC_E_NONE;
}

uint32
_sys_tmg_datapath_epe_speed_to_credit(uint16 speed)
{
    uint16 i = 0;
    const uint16 line_num = 9;
                              /*<   10, 10, 25, 40, 50, 100, 200, 400*/
    const uint16 speed_lines[] = {0, 1, 10, 25, 40, 50, 100, 200, 400};
    const uint32 credits[]     = {0, 6,  6, 11, 12, 21,  33,  40,  80};

    while((i < line_num) && (speed > speed_lines[i]))
    {
        i++;
    }
    SYS_CONDITION_RETURN((i >= line_num), 0);

    return credits[i];
}

int32
_sys_tmg_datapath_set_epe_credit(uint8 lchip, uint8 dp, uint16 mac_client, uint8 speed_mode)
{
    uint32  index           = 0;
    uint32  cmd             = 0;
    uint32  credit          = 0;
    uint16  speed           = 0;
    uint32  txqm_mac_client = SYS_TMG_GET_TXQM_MAC_CLIENT(mac_client);
    uint32  tbl_id          = 0;
    EpeScheduleToNet0CreditConfigRa_m epe_credit  = {{0}};

    SYS_DATAPATH_MODE_TO_SPEED(speed_mode, speed);
    credit = _sys_tmg_datapath_epe_speed_to_credit(speed);
    index = DRV_INS(dp, txqm_mac_client);
    switch(SYS_TMG_GET_DP_TXQM(mac_client))
    {
        case 0:
            tbl_id = EpeScheduleToNet0CreditConfigRa_t;
            break;
        case 1:
            tbl_id = EpeScheduleToNet1CreditConfigRa_t;
            break;
        case 2:
            tbl_id = EpeScheduleToNet2CreditConfigRa_t;
            break;
        case 3:
            tbl_id = EpeScheduleToNet3CreditConfigRa_t;
            break;
        case 4:
        default:
            tbl_id = EpeScheduleToNet4CreditConfigRa_t;
            break;
    }

    cmd = DRV_IOR(tbl_id, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &epe_credit));
    DRV_IOW_FIELD_NZ(lchip, tbl_id, EpeScheduleToNet0CreditConfigRa_cfgCreditValue_f, &credit, &epe_credit,
        dp, txqm_mac_client);
    cmd = DRV_IOW(tbl_id, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &epe_credit));

    return CTC_E_NONE;
}

int32
_sys_tmg_datapath_set_sp_chan(uint8 lchip, uint8 dp)
{
    uint8  i;
    uint32 cmd       = 0;
    uint32 fld_id    = 0;
    uint32 entry_id  = 0;
    uint32 tmp_val32 = 0x7f;
    BufRetrvDPWrrCtl_m wrr_ctl;

    entry_id = DRV_INS(dp, 0);
    cmd = DRV_IOR(BufRetrvDPWrrCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, entry_id, cmd, &wrr_ctl));

    for(i = 0; i < 8; i++)
    {
        dmps_BufRetrvDPWrrCtl_cfgSpChan0_f(i, fld_id);
        DRV_IOW_FIELD_NZ(lchip, BufRetrvDPWrrCtl_t, fld_id, &tmp_val32, &wrr_ctl, dp, 0);
    }

    cmd = DRV_IOW(BufRetrvDPWrrCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, entry_id, cmd, &wrr_ctl));

    return CTC_E_NONE;
}

/*set NetRxAdmissionCfg.cfgLongPktPri 1 to avoid long packet cut in super wide bandwidth*/
int32
_sys_tmg_datapath_set_netrx_longpktpri_dp(uint8 lchip, uint8 dp)
{
    uint32  cmd   = 0;
    uint32  entry = DRV_INS(dp, 0);
    uint32  value = 1;
    NetRxAdmissionCfg_m nrx_cfg;

    cmd = DRV_IOR(NetRxAdmissionCfg_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, entry, cmd, &nrx_cfg));
    DRV_IOW_FIELD_NZ(lchip, NetRxAdmissionCfg_t, NetRxAdmissionCfg_cfgLongPktPri_f, &value, &nrx_cfg, dp, 0);
    cmd = DRV_IOW(NetRxAdmissionCfg_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, entry, cmd, &nrx_cfg));

    return CTC_E_NONE;
}

int32
_sys_tmg_datapath_set_qmgr_xglg_en(uint8 lchip, uint8 dp)
{
    /*uint16 chan_id         = 0;*/
    /*uint16 dp_chan         = 0;*/
    uint32 cmd               = 0;
    uint32 xg_bitmap[2]    = {0xffffffff, 0xffffffff}; //64 bit per dp, dp_chan
    uint32 lg_bitmap[2]    = {0xffffffff, 0xffffffff}; //64 bit per dp, dp_chan
    /*uint32 speed           = 0;*/
    /*uint8  speed_mode      = 0;*/
    /*sys_dmps_db_upt_info_t port_info = {0};*/
    QMgrDeqChanIdCfg_m     qmd_cfg;

    /*qmgr speed, channel, NW & MISC*/
    /*for(dp_chan = 0; dp_chan < SYS_TMG_CHANNEL_NUM_PER_DP; dp_chan++)
    {
        chan_id = SYS_TMG_DPCHAN_TO_CHANNEL(dp_chan, dp);
        SYS_CONDITION_CONTINUE(FALSE == sys_usw_dmps_db_is_valid_id(lchip, DMPS_DB_TYPE_CHAN, chan_id));

        CTC_ERROR_RETURN(sys_usw_dmps_db_upt_info_init(lchip, &port_info));
        DMPS_DB_SET_MAP_INFO(port_info, DMPS_DB_TYPE_CHAN, chan_id);
        DMPS_DB_SET_PROPERTY_UPDATE(port_info, DMPS_DB_CHAN_SPEED_MODE);
        CTC_ERROR_RETURN(sys_usw_dmps_db_get_port_info(lchip, &port_info));
        DMPS_DB_GET_PROPERTY_INFO(port_info, DMPS_DB_CHAN_SPEED_MODE, speed_mode);

        SYS_DATAPATH_MODE_TO_SPEED(speed_mode, speed);
        if(speed < 50)
        {
            CTC_BMP_SET(xg_bitmap,   dp_chan);
            CTC_BMP_UNSET(lg_bitmap, dp_chan);
        }
        else
        {
            CTC_BMP_SET(lg_bitmap,   dp_chan);
            CTC_BMP_UNSET(xg_bitmap, dp_chan);
        }
    }*/

    cmd = DRV_IOR(QMgrDeqChanIdCfg_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &qmd_cfg));
    if(0 == dp)
    {
        DRV_IOW_FIELD(lchip, QMgrDeqChanIdCfg_t, QMgrDeqChanIdCfg_gDp_0_cfgLGChanEn_f, lg_bitmap, &qmd_cfg);
        DRV_IOW_FIELD(lchip, QMgrDeqChanIdCfg_t, QMgrDeqChanIdCfg_gDp_0_cfgXGChanEn_f, xg_bitmap, &qmd_cfg);
    }
    else
    {
        DRV_IOW_FIELD(lchip, QMgrDeqChanIdCfg_t, QMgrDeqChanIdCfg_gDp_1_cfgLGChanEn_f, lg_bitmap, &qmd_cfg);
        DRV_IOW_FIELD(lchip, QMgrDeqChanIdCfg_t, QMgrDeqChanIdCfg_gDp_1_cfgXGChanEn_f, xg_bitmap, &qmd_cfg);
    }
    cmd = DRV_IOW(QMgrDeqChanIdCfg_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &qmd_cfg));

    return CTC_E_NONE;
}

int32
_sys_tmm_datapath_set_nettx_ready(uint8 lchip, uint8 dp)
{
    uint32 cmd       = 0;
    uint32 entry     = DRV_INS(dp, 0);
    uint32 tmp_val32 = 1;
    NetTxMiscCtl_m msc_ctl;

    cmd = DRV_IOR(NetTxMiscCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, entry, cmd, &msc_ctl));
    DRV_IOW_FIELD_NZ(lchip, NetTxMiscCtl_t, NetTxMiscCtl_netTxReady_f, &tmp_val32, &msc_ctl, dp, 0);
    cmd = DRV_IOW(NetTxMiscCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, entry, cmd, &msc_ctl));

    return CTC_E_NONE;
}

int32
_sys_tmg_datapath_static_init(uint8 lchip)
{
    uint32  index      = 0;
    uint32  cmd        = 0;
    uint32  value      = 0;
    uint8   dp         = 0;
    EpeHdrEditExtraCreditConfig_m epe_ext;
    QMgrMsgMiscDrainEnable_m      qmg_drn;

    for(dp = 0; dp < SYS_TMG_DP_NUM; dp++)
    {
        CTC_ERROR_RETURN(_sys_tmm_datapath_set_nettx_ready(lchip, dp));
        CTC_ERROR_RETURN(_sys_tmg_datapath_init_extra_cfg_dp(lchip, dp));
        CTC_ERROR_RETURN(_sys_tmg_datapath_set_qmgr_xglg_en(lchip, dp));
        CTC_ERROR_RETURN(_sys_tmg_datapath_set_sp_chan(lchip, dp));
        CTC_ERROR_RETURN(_sys_tmg_datapath_set_netrx_longpktpri_dp(lchip, dp));
    }

    /*write EpeHdrEditExtraCreditConfig.extraCreditUplink 2 to solve stacking port queue blocked*/
    cmd = DRV_IOR(EpeHdrEditExtraCreditConfig_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &epe_ext));
    value = 2;
    DRV_IOW_FIELD(lchip, EpeHdrEditExtraCreditConfig_t, EpeHdrEditExtraCreditConfig_extraCreditUplink_f, &value, &epe_ext);
    cmd = DRV_IOW(EpeHdrEditExtraCreditConfig_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &epe_ext));

    /*QMgrMsgMiscDrainEnable.freePtrDrainEnable set 1*/
    cmd = DRV_IOR(QMgrMsgMiscDrainEnable_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &qmg_drn));
    value = 1;
    DRV_IOW_FIELD(lchip, QMgrMsgMiscDrainEnable_t, QMgrMsgMiscDrainEnable_freePtrDrainEnable_f, &value, &qmg_drn);
    cmd = DRV_IOW(QMgrMsgMiscDrainEnable_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &qmg_drn));

    return CTC_E_NONE;
}

int32
_sys_tmg_datapath_epe_info_collect(uint8 lchip, uint8 dp, uint8 dp_txqm, 
                                              uint16* p_xg_bmp, uint16* p_lg_bmp, 
                                              uint16* p_wl_sum, uint16* p_wh_sum, 
                                              uint16 wp[SYS_TMG_MAC_CLIENT_NUM_PER_TXQM])
{
    uint16 mac_id = 0;
    uint16 txqm_mac = 0;
    uint16 txqm_mac_client = 0;
    uint16 mac_client      = 0;
    uint16 xg_bmp = 0;     /* 16bit is for mac client 0~15 */
    uint16 lg_bmp = 0;
    sys_dmps_db_upt_info_t port_info = {0};
    uint8  speed_mode      = 0;
    uint16 speed           = 0;
    uint16 dport           = 0;
    uint8  port_type       = 0;
    uint16 weight          = 0;
    uint8  idx;
    uint16 chan_id         = 0;
    uint8  p_chan_num      = 0;
    uint16 wl_sum          = 0;
    uint16 wh_sum          = 0;
    uint16 p_chan_id[DMPS_MAX_NUM_PER_MODULE] = {0};

    for(txqm_mac = 0; txqm_mac < SYS_TMG_MAC_NUM_PER_TXQM; txqm_mac++)
    {
        mac_id = SYS_TMG_MAX_MAC_NUM_PER_DP * dp + SYS_TMG_MAC_NUM_PER_TXQM * dp_txqm + txqm_mac;
        SYS_CONDITION_CONTINUE(FALSE == sys_usw_dmps_db_is_valid_id(lchip, DMPS_DB_TYPE_MAC, mac_id));
        
        SYS_CONDITION_CONTINUE(CTC_E_NONE != sys_usw_dmps_db_get_relative_id(lchip, DMPS_DB_TYPE_MAC, mac_id, 
            DMPS_DB_TYPE_PORT, NULL, &dport));        
        SYS_CONDITION_CONTINUE(CTC_E_NONE != sys_usw_dmps_db_get_relative_id(lchip, DMPS_DB_TYPE_PORT, dport, 
            GET_CHAN_TYPE_BY_DIR(CHAN_DIR_TX), &p_chan_num, p_chan_id));
        for(idx = 0; idx < p_chan_num; idx++)
        {
            chan_id = p_chan_id[idx];
            CTC_ERROR_RETURN(sys_usw_dmps_db_upt_info_init(lchip, &port_info));
            DMPS_DB_SET_MAP_INFO(port_info, GET_CHAN_ID_BY_DIR(CHAN_DIR_TX), chan_id);
            DMPS_DB_SET_PROPERTY_UPDATE(port_info, DMPS_DB_PORT_TYPE);
            DMPS_DB_SET_PROPERTY_UPDATE(port_info, DMPS_DB_CHAN_SPEED_MODE);
            DMPS_DB_SET_PROPERTY_UPDATE(port_info, DMPS_DB_CHAN_MAC_CLIENT_ID);
            CTC_ERROR_RETURN(sys_usw_dmps_db_get_port_info(lchip, &port_info));
            DMPS_DB_GET_PROPERTY_INFO(port_info, DMPS_DB_PORT_TYPE,       port_type);
            DMPS_DB_GET_PROPERTY_INFO(port_info, DMPS_DB_CHAN_SPEED_MODE, speed_mode);
            DMPS_DB_GET_PROPERTY_INFO(port_info, DMPS_DB_CHAN_MAC_CLIENT_ID, mac_client);

            /*allow NW*/
            SYS_CONDITION_CONTINUE(port_type != SYS_DMPS_NETWORK_PORT);
            
            SYS_DATAPATH_MODE_TO_SPEED(speed_mode, speed);
            SYS_DATAPATH_SPEED_TO_WRRCFG(speed_mode, weight);
            txqm_mac_client = SYS_TMG_GET_TXQM_MAC_CLIENT(mac_client);

            if(speed < 50)
            {
                CTC_BIT_SET(xg_bmp, txqm_mac_client);   //CTC_BMP_SET(&xg_bmp, txqm_mac_client);
                CTC_BIT_UNSET(lg_bmp, txqm_mac_client); //CTC_BMP_UNSET(&lg_bmp, txqm_mac_client);
                wl_sum += weight;
            }
            else
            {
                CTC_BIT_UNSET(xg_bmp, txqm_mac_client); //CTC_BMP_UNSET(&xg_bmp, txqm_mac_client);
                CTC_BIT_SET(lg_bmp, txqm_mac_client);   //CTC_BMP_SET(&lg_bmp, txqm_mac_client);
                wh_sum += weight;
            }
            if(NULL != wp) wp[txqm_mac_client] = weight;
        }
    }
    SYS_USW_VALID_PTR_WRITE(p_xg_bmp, xg_bmp);
    SYS_USW_VALID_PTR_WRITE(p_lg_bmp, lg_bmp);
    SYS_USW_VALID_PTR_WRITE(p_wl_sum, wl_sum);
    SYS_USW_VALID_PTR_WRITE(p_wh_sum, wh_sum);

    return CTC_E_NONE;
}

/*EpeSchedulePortEnableCfg (dp, 0) cfgGroupXPortEn TXQM*/
int32
_sys_tmg_datapath_epe_port_enable(uint8 lchip, uint8 dp, uint32 dp_txqm, uint32 bmp)
{
    uint32 cmd             = 0;
    uint32 entry_id        = DRV_INS(dp, 0);
    uint32 fld[SYS_TMG_TXQM_NUM_PER_DP] = {
        EpeSchedulePortEnableCfg_cfgGroup0PortEn_f, 
        EpeSchedulePortEnableCfg_cfgGroup1PortEn_f, 
        EpeSchedulePortEnableCfg_cfgGroup2PortEn_f, 
        EpeSchedulePortEnableCfg_cfgGroup3PortEn_f, 
        EpeSchedulePortEnableCfg_cfgGroup4PortEn_f}; //the offset is changed in group 4, so...
    EpeSchedulePortEnableCfg_m port_en_cfg;

    cmd = DRV_IOR(EpeSchedulePortEnableCfg_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, entry_id, cmd, &port_en_cfg));
    DRV_IOW_FIELD_NZ(lchip, EpeSchedulePortEnableCfg_t, fld[dp_txqm], &bmp, &port_en_cfg, dp, 0);
    cmd = DRV_IOW(EpeSchedulePortEnableCfg_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, entry_id, cmd, &port_en_cfg));

    return CTC_E_NONE;
}

/*EpeScheduleNetPortWeightConfig0Ra (dp, txqm_mac_client)*/
int32
_sys_tmg_datapath_epe_nw_weight_cfg(uint8 lchip, uint8 dp, uint8 dp_txqm, uint16 net_weights[SYS_TMG_MAC_CLIENT_NUM_PER_TXQM])
{
    uint16 txqm_mac_client;
    uint32 index        = 0;
    uint32 cmd          = 0;
    uint32 opt_weight   = 0;
    uint16 divisor      = 0;
    uint32 tbl_id       = 0;
    EpeScheduleNetPortWeightConfig0Ra_m net_port_weight_cfg;

    dmps_EpeScheduleNetPortWeightConfig0Ra_t(dp_txqm, tbl_id);
    CTC_ERROR_RETURN(sys_usw_datapath_get_gcd(net_weights, SYS_TMG_MAC_CLIENT_NUM_PER_TXQM, &divisor));
    for(txqm_mac_client = 0; txqm_mac_client < SYS_TMG_MAC_CLIENT_NUM_PER_TXQM; txqm_mac_client++)
    {
        opt_weight = (0 == net_weights[txqm_mac_client]) ? 1 : (net_weights[txqm_mac_client] / divisor);

        index = DRV_INS(dp, txqm_mac_client);
        cmd = DRV_IOR(tbl_id, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &net_port_weight_cfg));
        DRV_IOW_FIELD_NZ(lchip, tbl_id, EpeScheduleNetPortWeightConfig0Ra_cfgWeight_f, &opt_weight, &net_port_weight_cfg, 
            dp, txqm_mac_client);
        cmd = DRV_IOW(tbl_id, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &net_port_weight_cfg));
    }

    return CTC_E_NONE;
}

///TODO: need change
int32
_sys_tmg_datapath_epe_misc_weight_cfg(uint8 lchip, uint8 dp)
{
    uint32 cmd        = 0;
    uint32 fld_id     = 0;
    uint32 opt_weight = 0;
    uint32 entry_id   = 0;
    uint16 divisor    = 0;
    uint8  idx        = 0;
    EpeScheduleMiscChanWeightConfig_m misc_chan_weight_cfg;

    CTC_ERROR_RETURN(sys_usw_datapath_get_gcd(g_tmg_misc_wrr_weight, 9, &divisor));
    cmd = DRV_IOR(EpeScheduleMiscChanWeightConfig_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, entry_id, cmd, &misc_chan_weight_cfg));
    
    entry_id = DRV_INS(dp, 0);
    for(idx = 0; idx < 9; idx++)
    {
        opt_weight = g_tmg_misc_wrr_weight[idx] / divisor;
        dmps_EpeScheduleMiscChanWeightConfig_toCpuMac0WtCfg_f(idx, fld_id);
        DRV_IOW_FIELD_NZ(lchip, EpeScheduleMiscChanWeightConfig_t, fld_id, &opt_weight, &misc_chan_weight_cfg, dp, 0);
    }

    cmd = DRV_IOW(EpeScheduleMiscChanWeightConfig_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, entry_id, cmd, &misc_chan_weight_cfg));

    return CTC_E_NONE;
}

/*EpeScheduleWrrWeightConfig (dp, 0)*/
int32
_sys_tmg_datapath_epe_wrr_weight_cfg(uint8 lchip, uint8 dp, uint16 wl_sum[SYS_TMG_TXQM_NUM_PER_DP],
                                             uint16 wh_sum[SYS_TMG_TXQM_NUM_PER_DP])
{
    uint8  idx;
    uint8  dp_txqm;
    uint16 divisor        = 0;
    uint32 opt_weight     = 0;
    uint32 entry_id       = DRV_INS(dp, 0);
    uint32 cmd            = 0;
    uint32 fld_id         = 0;
    uint16 group7[2]      = {0};    //index: [0 or 1, network or misc port]
    uint16 txqm_weight[SYS_TMG_TXQM_NUM_PER_DP] = {0};    //high + low in every txqm    index: [dp_txqm]
    EpeScheduleWrrWeightConfig_m wrr_cfg;

    /*info collection*/
    for(dp_txqm = 0; dp_txqm < SYS_TMG_TXQM_NUM_PER_DP; dp_txqm++)
    {
        txqm_weight[dp_txqm] = wh_sum[dp_txqm] + wl_sum[dp_txqm];
        group7[0] += txqm_weight[dp_txqm];
    }
    CTC_ERROR_RETURN(sys_usw_datapath_get_gcd(txqm_weight, SYS_TMG_TXQM_NUM_PER_DP, &divisor));

    cmd = DRV_IOR(EpeScheduleWrrWeightConfig_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, entry_id, cmd, &wrr_cfg));

    /*network port*/
    for(dp_txqm = 0; dp_txqm < SYS_TMG_TXQM_NUM_PER_DP; dp_txqm++)
    {
        opt_weight = txqm_weight[dp_txqm] / divisor;
        dmps_EpeScheduleWrrWeightConfig_cfgGroup5Txqm0WtCfg_f(dp_txqm, fld_id);
        DRV_IOW_FIELD_NZ(lchip, EpeScheduleWrrWeightConfig_t, fld_id, &opt_weight, &wrr_cfg, dp, 0);
    }

    /* GROUP 7: net & misc */
    for(idx = 0; idx < 9; idx++)
    {
        group7[1] += g_tmg_misc_wrr_weight[idx];
    }
    group7[1] *= 10;
    CTC_ERROR_RETURN(sys_usw_datapath_get_gcd(group7, 2, &divisor));
    opt_weight = group7[0] / divisor;
    DRV_IOW_FIELD_NZ(lchip, EpeScheduleWrrWeightConfig_t, EpeScheduleWrrWeightConfig_cfgGroup7NetWtCfg_f,
        &opt_weight, &wrr_cfg, dp, 0);
    opt_weight = group7[1] / divisor;
    DRV_IOW_FIELD_NZ(lchip, EpeScheduleWrrWeightConfig_t, EpeScheduleWrrWeightConfig_cfgGroup7MiscWtCfg_f,
        &opt_weight, &wrr_cfg, dp, 0);

    cmd = DRV_IOW(EpeScheduleWrrWeightConfig_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, entry_id, cmd, &wrr_cfg));

    return CTC_E_NONE;
}

///TODO: misc port id??
int32
_sys_tmg_datapath_epe_misc_port_id_cfg(uint8 lchip, uint8 dp_id)
{
    uint32  index      = 0;
    uint32  cmd        = 0;
    uint32  value      = 0;
    EpeSchedulePortIdCfg_m epe_port;

    index = DRV_INS(dp_id, 0);
    cmd = DRV_IOR(EpeSchedulePortIdCfg_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &epe_port));
    value = 0xa2; //CPUMAC 0: 162
    DRV_IOW_FIELD_NZ(lchip, EpeSchedulePortIdCfg_t, EpeSchedulePortIdCfg_cfgCpuMac0PortId_f, &value, &epe_port, dp_id, 0);
    value = 0xa3; //CPUMAC 1: 163
    DRV_IOW_FIELD_NZ(lchip, EpeSchedulePortIdCfg_t, EpeSchedulePortIdCfg_cfgCpuMac1PortId_f, &value, &epe_port, dp_id, 0);
    value = 0xa0; //DMA 0: 160
    DRV_IOW_FIELD_NZ(lchip, EpeSchedulePortIdCfg_t, EpeSchedulePortIdCfg_cfgDma0PortId_f,    &value, &epe_port, dp_id, 0);
    value = 0xa1; //DMA 1: 161
    DRV_IOW_FIELD_NZ(lchip, EpeSchedulePortIdCfg_t, EpeSchedulePortIdCfg_cfgDma1PortId_f,    &value, &epe_port, dp_id, 0);

    cmd = DRV_IOW(EpeSchedulePortIdCfg_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &epe_port));

    return CTC_E_NONE;
}

STATIC int32
_sys_tmg_datapath_epe_init(uint8 lchip, uint8 dp)
{
    uint16 dp_chan    = 0;
    uint16 chan_id    = 0;
    uint16 mac_client = 0;
    uint8  speed_mode = 0;
    uint8  port_type  = 0;
    uint16 wl_sum[SYS_TMG_TXQM_NUM_PER_DP]     = {0};
    uint16 wh_sum[SYS_TMG_TXQM_NUM_PER_DP]     = {0};
    uint16 wp[SYS_TMG_MAC_CLIENT_NUM_PER_TXQM] = {0};
    uint8  dp_txqm    = 0;
    sys_dmps_db_upt_info_t port_info = {0};

    for(dp_chan = 0; dp_chan < SYS_TMG_CHANNEL_NUM_PER_DP; dp_chan++)
    {
        chan_id = SYS_TMG_DPCHAN_TO_CHANNEL(dp_chan, dp);
        SYS_CONDITION_CONTINUE(FALSE == sys_usw_dmps_db_is_valid_id(lchip, GET_CHAN_TYPE_BY_DIR(CHAN_DIR_TX), chan_id));
        
        CTC_ERROR_RETURN(sys_usw_dmps_db_upt_info_init(lchip, &port_info));
        DMPS_DB_SET_MAP_INFO(port_info, GET_CHAN_ID_BY_DIR(CHAN_DIR_TX), chan_id);
        DMPS_DB_SET_PROPERTY_UPDATE(port_info, DMPS_DB_PORT_TYPE);
        DMPS_DB_SET_PROPERTY_UPDATE(port_info, DMPS_DB_CHAN_SPEED_MODE);
        DMPS_DB_SET_PROPERTY_UPDATE(port_info, DMPS_DB_CHAN_MAC_CLIENT_ID);
        CTC_ERROR_RETURN(sys_usw_dmps_db_get_port_info(lchip, &port_info));
        DMPS_DB_GET_PROPERTY_INFO(port_info, DMPS_DB_PORT_TYPE,       port_type);
        DMPS_DB_GET_PROPERTY_INFO(port_info, DMPS_DB_CHAN_SPEED_MODE, speed_mode);
        DMPS_DB_GET_PROPERTY_INFO(port_info, DMPS_DB_CHAN_MAC_CLIENT_ID, mac_client);

        if(SYS_DMPS_NETWORK_PORT == port_type)
        {
            /*nw only*/
            CTC_ERROR_RETURN(_sys_tmg_datapath_set_epe_credit(lchip, dp, mac_client, speed_mode));
        }
    }

    for(dp_txqm = 0; dp_txqm < SYS_TMG_TXQM_NUM_PER_DP; dp_txqm++)
    {
        CTC_ERROR_RETURN(_sys_tmg_datapath_epe_info_collect(lchip, dp, dp_txqm, 
            NULL, NULL, &(wl_sum[dp_txqm]), &(wh_sum[dp_txqm]), wp));

        CTC_ERROR_RETURN(_sys_tmg_datapath_epe_port_enable(lchip, dp, dp_txqm, 0xffff));
        /*config network port epe weight*/
        CTC_ERROR_RETURN(_sys_tmg_datapath_epe_nw_weight_cfg(lchip, dp, dp_txqm, wp));
    }
    /*config wrr ls & hs weight*/
    CTC_ERROR_RETURN(_sys_tmg_datapath_epe_wrr_weight_cfg(lchip, dp, wl_sum, wh_sum));
    /*config misc port epe weight*/
    CTC_ERROR_RETURN(_sys_tmg_datapath_epe_misc_weight_cfg(lchip, dp));

    /*CTC_ERROR_RETURN(_sys_tmg_datapath_epe_misc_port_id_cfg(lchip, dp));*/

    return CTC_E_NONE;
}

/*NetTxCreditThrd (dp, dp_mac_id)*/
int32
_sys_tmg_datapath_set_nettx_credit(uint8 lchip, uint8 dp, uint16 dp_mac_id, uint16 speed)
{
    uint32  cmd       = 0;
    uint32  index     = 0;
    uint32  credit    = SYS_TMG_GET_NETTX_CREDIT_FROM_SPEED(speed);
    NetTxCreditThrd_m credit_cfg;

    SYS_CONDITION_RETURN(SYS_TMG_MACID_NUM_PER_DP <= dp_mac_id, CTC_E_INVALID_CONFIG);

    index = DRV_INS(dp, dp_mac_id);

    cmd = DRV_IOR(NetTxCreditThrd_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &credit_cfg));
    DRV_IOW_FIELD_NZ(lchip, NetTxCreditThrd_t, NetTxCreditThrd_data_f, &credit, &credit_cfg, dp, dp_mac_id);
    cmd = DRV_IOW(NetTxCreditThrd_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &credit_cfg));

    return CTC_E_NONE;
}

uint32
_sys_tmg_datapath_get_dp_bw(uint8 lchip, uint8 dir, uint8 dp)
{
    uint16 dp_chan         = 0;
    uint16 chan_id         = 0;
    uint8  speed_mode      = 0;
    uint16 speed           = 0;
    uint32 total_bw        = 0;
    uint16 prop            = CHAN_DIR_IS_RX(dir) ? DMPS_DB_CHAN_RX_SPEED_MODE : DMPS_DB_CHAN_SPEED_MODE;
    sys_dmps_db_upt_info_t port_info = {0};

    for(dp_chan = 0; dp_chan < SYS_TMG_CHANNEL_NUM_PER_DP; dp_chan++)
    {
        chan_id = SYS_TMG_DPCHAN_TO_CHANNEL(dp_chan, dp);
        SYS_CONDITION_CONTINUE(FALSE == sys_usw_dmps_db_is_valid_id(lchip, GET_CHAN_TYPE_BY_DIR(dir), chan_id));

        CTC_ERROR_RETURN(sys_usw_dmps_db_upt_info_init(lchip, &port_info));
        DMPS_DB_SET_MAP_INFO(port_info, DMPS_DB_CHAN_RX_ID, chan_id);
        DMPS_DB_SET_PROPERTY_UPDATE(port_info, prop);
        CTC_ERROR_RETURN(sys_usw_dmps_db_get_port_info(lchip, &port_info));
        DMPS_DB_GET_PROPERTY_INFO(port_info, prop, speed_mode);

        SYS_DATAPATH_MODE_TO_SPEED(speed_mode, speed);
        total_bw += speed;
    }
    return total_bw;
}

uint8
_sys_tmg_datapath_judge_nettx_longbufmode(uint8 lchip, uint8 dp_id, uint32 total_bw_given)
{
    uint32  total_bw           = 0;
    uint8   longbufmode_flag   = FALSE;

    if(650 >= sys_usw_datapath_get_core_clock(lchip, 0))
    {
        total_bw = (DMPS_INVALID_VALUE_U32 == total_bw_given) ? _sys_tmg_datapath_get_dp_bw(lchip, CHAN_DIR_TX, dp_id) :
            total_bw_given;
        if(600 <= total_bw)
        {
            longbufmode_flag = TRUE;
        }
    }

    return longbufmode_flag;
}

/*NetTxTimerEnCtl (dp, 0)*/
/*NetTxTxTimerThrdCfg (dp, dp_mac_client)*/
/*NetTxTxThrdCfg (dp, dp_mac_client)*/
/*txTimerEn optimized*/
int32
_sys_tmg_datapath_set_nettx_timer(uint8 lchip, uint8 dp, uint16 dp_mac_client, uint8 dp_txqm, 
                                             uint16 speed, uint32 total_bw)
{
    uint16 core_pll         = 0;
    uint32 entry            = 0;
    uint32 cmd              = 0;
    uint32 fld_id           = 0;
    uint32 tmr_en_bmp       = 0;
    uint32 grt_thd          = 2;
    uint16 txqm_mac_client  = SYS_TMG_GET_TXQM_MAC_CLIENT(dp_mac_client);
    uint32 tmp_val32        = ((uint32)0x1) << txqm_mac_client;
    uint8  lbf_mode         = _sys_tmg_datapath_judge_nettx_longbufmode(lchip, dp, total_bw);
    NetTxTimerEnCtl_m       tmr_en;
    NetTxTxTimerThrdCfg_m   tmr_thd;
    NetTxTxThrdCfg_m        tx_thd;

    /*1. Timer en*/
    entry = DRV_INS(dp, 0);
    cmd = DRV_IOR(NetTxTimerEnCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, entry, cmd, &tmr_en));
    fld_id = NetTxTimerEnCtl_txTimerEn0_f + (NetTxTimerEnCtl_txTimerEn1_f - NetTxTimerEnCtl_txTimerEn0_f)*dp_txqm;
    DRV_IOR_FIELD(lchip, NetTxTimerEnCtl_t, fld_id, &tmr_en_bmp, &tmr_en);
    if(lbf_mode)
    {
        tmr_en_bmp &= (~tmp_val32);
    }
    else
    {
        /*speed <= 10G write 0*/
        if(speed <= 10)
        {
            tmr_en_bmp &= (~tmp_val32);
        }
        /*speed > 10G write 1*/
        else
        {
            tmr_en_bmp |= tmp_val32;
        }
    }
    DRV_IOW_FIELD(lchip, NetTxTimerEnCtl_t, fld_id, &tmr_en_bmp, &tmr_en);
    cmd = DRV_IOW(NetTxTimerEnCtl_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, entry, cmd, &tmr_en));

    /*2. Timer thrd*/
    entry = DRV_INS(dp, dp_mac_client);
    cmd = DRV_IOR(NetTxTxTimerThrdCfg_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, entry, cmd, &tmr_thd));
    tmp_val32 = speed >= 100 ? 28 :
                speed >= 50  ? 50 :
                speed >= 40  ? 64 :
                speed >= 25  ? 100 :
                speed >= 1   ? 140 : 0;
    DRV_IOW_FIELD_NZ(lchip, NetTxTxTimerThrdCfg_t, NetTxTxTimerThrdCfg_txTimerThrd_f, &tmp_val32, &tmr_thd, 
        dp, dp_mac_client);
    cmd = DRV_IOW(NetTxTxTimerThrdCfg_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, entry, cmd, &tmr_thd));

    /*3. Tx thrd*/
    cmd = DRV_IOR(NetTxTxThrdCfg_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, entry, cmd, &tx_thd));
    /*3.1 txthrd*/
    tmp_val32 = (total_bw > 600) ? 5 : 2;
    DRV_IOW_FIELD_NZ(lchip, NetTxTxThrdCfg_t, NetTxTxThrdCfg_txthrd_f, &tmp_val32, &tx_thd, dp, dp_mac_client);
    /*3.2 guaranteeTxThrd*/
    if((total_bw > 1000) || (speed < 25))
    {
        grt_thd = 3;
    }
    else
    {
        grt_thd = 2;
    }
    if(lbf_mode)
    {
        grt_thd += 2;
    }

    CTC_ERROR_RETURN(sys_usw_dmps_db_get_core_pll(lchip, &core_pll, 1));
    if (core_pll == 650)
    {
        grt_thd = 4;
    }
    
    DRV_IOW_FIELD_NZ(lchip, NetTxTxThrdCfg_t, NetTxTxThrdCfg_guaranteeTxThrd_f, &grt_thd, &tx_thd, dp, dp_mac_client);
    cmd = DRV_IOW(NetTxTxThrdCfg_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, entry, cmd, &tx_thd));

    return CTC_E_NONE;
}

/*NetTx, NW only*/
int32
_sys_tmg_datapath_nettx_init(uint8 lchip, uint8 dp)
{
    uint8  txqm            = 0;
    uint8  dp_txqm         = 0;
    uint8  port_type       = 0;
    uint8  speed_mode      = 0;
    uint16 speed           = 0;
    uint16 dp_chan         = 0;
    uint16 chan_id         = 0;
    uint16 mac_id          = 0;
    uint16 dp_mac_id       = 0;
    uint16 mac_client      = 0;
    uint16 dp_mac_client   = 0;
    uint32 total_bw        = _sys_tmg_datapath_get_dp_bw(lchip, CHAN_DIR_TX, dp);
    sys_dmps_db_upt_info_t port_info = {0};

    for(dp_chan = 0; dp_chan < SYS_TMG_CHANNEL_NUM_PER_DP; dp_chan++)
    {
        chan_id = SYS_TMG_DPCHAN_TO_CHANNEL(dp_chan, dp);
        SYS_CONDITION_CONTINUE(FALSE == sys_usw_dmps_db_is_valid_id(lchip, DMPS_DB_TYPE_CHAN, chan_id));

        CTC_ERROR_RETURN(sys_usw_dmps_db_upt_info_init(lchip, &port_info));
        DMPS_DB_SET_MAP_INFO(port_info, DMPS_DB_CHAN_ID, chan_id);
        DMPS_DB_SET_PROPERTY_UPDATE(port_info, DMPS_DB_PORT_TYPE);
        DMPS_DB_SET_PROPERTY_UPDATE(port_info, DMPS_DB_CHAN_RX_SPEED_MODE);
        DMPS_DB_SET_PROPERTY_UPDATE(port_info, DMPS_DB_CHAN_TXQM_ID);
        DMPS_DB_SET_PROPERTY_UPDATE(port_info, DMPS_DB_CHAN_MAC_CLIENT_ID);
        CTC_ERROR_RETURN(sys_usw_dmps_db_get_port_info(lchip, &port_info));
        DMPS_DB_GET_MAP_INFO(port_info, DMPS_DB_MAC_ID, mac_id);
        DMPS_DB_GET_PROPERTY_INFO(port_info, DMPS_DB_PORT_TYPE,          port_type);
        DMPS_DB_GET_PROPERTY_INFO(port_info, DMPS_DB_CHAN_RX_SPEED_MODE, speed_mode);
        DMPS_DB_GET_PROPERTY_INFO(port_info, DMPS_DB_CHAN_TXQM_ID,       txqm);
        DMPS_DB_GET_PROPERTY_INFO(port_info, DMPS_DB_CHAN_MAC_CLIENT_ID, mac_client);

        /*NW only*/
        SYS_CONDITION_CONTINUE(port_type != SYS_DMPS_NETWORK_PORT);
        
        dp_mac_client = SYS_TMG_GET_DP_MAC_CLIENT(mac_client);
        dp_txqm = SYS_TMG_GET_DP_TXQM_BY_TXQM(txqm);
        dp_mac_id = SYS_TMG_GET_DP_MAC_ID(mac_id);
        SYS_DATAPATH_MODE_TO_SPEED(speed_mode, speed);

        CTC_ERROR_RETURN(_sys_tmg_datapath_set_nettx_credit(lchip, dp, dp_mac_id, speed));
        CTC_ERROR_RETURN(_sys_tmg_datapath_set_nettx_timer(lchip, dp, dp_mac_client, dp_txqm, speed, total_bw));
    }

    return CTC_E_NONE;
}

/*get sub-divisor of[100, 50, 40, 25, 10]*/
uint8
_sys_tmg_datapath_speedmode_to_weight(uint8 speed_mode)
{
    uint8 credit = 0;
    /*sub-divisor of[100, 50, 40, 25, 10]*/
    switch(speed_mode)
    {
        case CTC_PORT_SPEED_100G:
            credit = 20;
            break;
        case CTC_PORT_SPEED_50G:
            credit = 10;
            break;
        case CTC_PORT_SPEED_40G:
            credit = 8;
            break;
        case CTC_PORT_SPEED_25G:
        case CTC_PORT_SPEED_20G:
            credit = 5;
            break;
        case 0:
            credit = 0;
            break;
        default:/*<=10G*/
            credit = 2;
            break;
    }
    return credit;
}

uint8
_sys_tmg_datapath_speedmode_to_qmgrcrdt(uint16 speed)
{
    uint8 credit = 0;
    /*sub-divisor of[100, 50, 40, 25, 10]*/
    switch(speed)
    {
        case 200:
            credit = 30;
            break;
        case 100:
            credit = 22;
            break;
        case 50:
            credit = 11;
            break;
        case 40:
            credit = 9;
            break;
        case 25:
        case 20:
            credit = 6;
            break;
        case 0:
            credit = 0;
            break;
        default:/*<=10G*/
            credit = 2;
            break;
    }
    return credit;
}

/*DsQMgrChanCredit (0, chan_id)*/
/*chan_id 0~127, NW & MISC*/
int32
_sys_tmg_datapath_set_qmgr_credit(uint8 lchip, uint16 chan_id, uint8 speed_mode)
{
    uint16 speed     = 0;
    uint32 cmd       = 0;
    uint32 credit    = 0;
    DsQMgrChanCredit_m qmc_crdt;

    SYS_DATAPATH_MODE_TO_SPEED(speed_mode, speed);
    credit = _sys_tmg_datapath_speedmode_to_qmgrcrdt(speed);

    SYS_CONDITION_RETURN(SYS_TMG_CHANNEL_NUM <= chan_id, CTC_E_INVALID_PARAM);

    cmd = DRV_IOR(DsQMgrChanCredit_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, chan_id, cmd, &qmc_crdt));

    DRV_IOW_FIELD_NZ(lchip, DsQMgrChanCredit_t, DsQMgrChanCredit_credit_f, &credit, &qmc_crdt, 0, chan_id);

    cmd = DRV_IOW(DsQMgrChanCredit_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, chan_id, cmd, &qmc_crdt));

    return CTC_E_NONE;
}

/*DsQMgrChanWeight (0, chan_id128)*/
/*QMgrDeqIntfWeightCfg (0, 0)*/
/*NW & MISC*/
int32
_sys_tmg_datapath_qmgr_wrr_cfg(uint8 lchip)
{
    uint8  dp           = 0;
    uint16 dp_chan      = 0;
    uint16 chan_id      = 0;
    uint8  speed_mode   = 0;
    uint32 speed        = 0;
    uint16 weight       = 0;
    uint32 opt_weight   = 0;
    uint32 cmd          = 0;
#if 0    
    uint8  grp_id       = 0;
    uint32 fld[2][2]    = {{QMgrDeqIntfWeightCfg_gDp_0_cfgLgWeight_f, QMgrDeqIntfWeightCfg_gDp_1_cfgLgWeight_f}, 
                           {QMgrDeqIntfWeightCfg_gDp_0_cfgXgWeight_f, QMgrDeqIntfWeightCfg_gDp_1_cfgXgWeight_f}};
#endif                           
    uint16 divisor      = 0;
    uint16 xg_lg[2][2]  = {{0}};
    uint16 weight_arr[SYS_TMG_CHANNEL_NUM] = {0};
    //- uint16 weight_dp[SYS_TMG_DP_NUM] = {0};
    sys_dmps_db_upt_info_t port_info = {0};
    //- QMgrDeqIntfWeightCfg_m  intf_weight_cfg;
    DsQMgrChanWeight_m      chan_weight;

    /*NW & MISC*/
    for(dp = 0; dp < SYS_TMG_DP_NUM; dp++)
    {
        for(dp_chan = 0; dp_chan < SYS_TMG_CHANNEL_NUM_PER_DP; dp_chan++)
        {
            chan_id = SYS_TMG_DPCHAN_TO_CHANNEL(dp_chan, dp);
            SYS_CONDITION_CONTINUE(FALSE == sys_usw_dmps_db_is_valid_id(lchip, DMPS_DB_TYPE_CHAN, chan_id));
            SYS_CONDITION_RETURN(SYS_TMG_CHANNEL_NUM <= chan_id, CTC_E_INVALID_PARAM);
            
            CTC_ERROR_RETURN(sys_usw_dmps_db_upt_info_init(lchip, &port_info));
            DMPS_DB_SET_MAP_INFO(port_info, DMPS_DB_CHAN_ID, chan_id);
            DMPS_DB_SET_PROPERTY_UPDATE(port_info, DMPS_DB_CHAN_SPEED_MODE);
            CTC_ERROR_RETURN(sys_usw_dmps_db_get_port_info(lchip, &port_info));
            DMPS_DB_GET_PROPERTY_INFO(port_info, DMPS_DB_CHAN_SPEED_MODE, speed_mode);

            SYS_DATAPATH_SPEED_TO_WRRCFG(speed_mode, weight);
            SYS_DATAPATH_MODE_TO_SPEED(speed_mode, speed);
            if(speed < 50)
            {
                xg_lg[dp][0]  += weight;
            }
            else
            {
                xg_lg[dp][1]  += weight;
            }
            weight_arr[chan_id] = weight;
        }
        //- weight_dp[dp] = xg_lg[dp][0] + xg_lg[dp][1];
    }

    /*XG&LG WRR, inter-dp*/
    CTC_ERROR_RETURN(sys_usw_datapath_get_gcd(weight_arr, SYS_TMG_CHANNEL_NUM, &divisor));
    for(chan_id = 0; chan_id < SYS_TMG_CHANNEL_NUM; chan_id++)
    {
        cmd = DRV_IOR(DsQMgrChanWeight_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, chan_id, cmd, &chan_weight));

        opt_weight = weight_arr[chan_id] / divisor;

        DRV_IOW_FIELD_NZ(lchip, DsQMgrChanWeight_t, DsQMgrChanWeight_weight_f, &opt_weight, &chan_weight, 0, chan_id);
        cmd = DRV_IOW(DsQMgrChanWeight_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, chan_id, cmd, &chan_weight));
    }

#if 0
    cmd = DRV_IOR(QMgrDeqIntfWeightCfg_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &intf_weight_cfg));
    /*XG&LG WRR, inner-dp*/
    for(dp = 0; dp < SYS_TMG_DP_NUM; dp++)
    {
        CTC_ERROR_RETURN(sys_usw_datapath_get_gcd(xg_lg[dp], 2, &divisor));
        for(grp_id = 0; grp_id < 2; grp_id++)
        {
            opt_weight = xg_lg[dp][grp_id] / divisor;
            DRV_IOW_FIELD_NZ(lchip, QMgrDeqIntfWeightCfg_t, fld[dp][grp_id], &opt_weight, &intf_weight_cfg, 0, 0);
        }
    }
    /*Total bw WRR, inter-dp*/
    CTC_ERROR_RETURN(sys_usw_datapath_get_gcd(weight_dp, 2, &divisor));
    opt_weight = weight_dp[0] /divisor;
    DRV_IOW_FIELD_NZ(lchip, QMgrDeqIntfWeightCfg_t, QMgrDeqIntfWeightCfg_cfgDp0Weight_f, &opt_weight, &intf_weight_cfg, 0, 0);
    opt_weight = weight_dp[1] /divisor;
    DRV_IOW_FIELD_NZ(lchip, QMgrDeqIntfWeightCfg_t, QMgrDeqIntfWeightCfg_cfgDp1Weight_f, &opt_weight, &intf_weight_cfg, 0, 0);

    cmd = DRV_IOW(QMgrDeqIntfWeightCfg_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &intf_weight_cfg));
#endif
    return CTC_E_NONE;
}

int32
_sys_tmg_datapath_inter_dp_cfg(uint8 lchip)
{
    CTC_ERROR_RETURN(_sys_tmg_datapath_qmgr_wrr_cfg(lchip));

    return CTC_E_NONE;
}

int32
_sys_tmg_datapath_qmgr_crdt_init(uint8 lchip, uint8 dp)
{
    uint16 chan_id         = 0;
    uint16 dp_chan         = 0;
    uint8  speed_mode      = 0;
    sys_dmps_db_upt_info_t port_info = {0};
    
    /*qmgr credit, channel, NW & MISC*/
    for(dp_chan = 0; dp_chan < SYS_TMG_CHANNEL_NUM_PER_DP; dp_chan++)
    {
        chan_id = SYS_TMG_DPCHAN_TO_CHANNEL(dp_chan, dp);
        if(sys_usw_dmps_db_is_valid_id(lchip, DMPS_DB_TYPE_CHAN, chan_id))
        {
            CTC_ERROR_RETURN(sys_usw_dmps_db_upt_info_init(lchip, &port_info));
            DMPS_DB_SET_MAP_INFO(port_info, DMPS_DB_CHAN_ID, chan_id);
            DMPS_DB_SET_PROPERTY_UPDATE(port_info, DMPS_DB_CHAN_SPEED_MODE);
            CTC_ERROR_RETURN(sys_usw_dmps_db_get_port_info(lchip, &port_info));
            DMPS_DB_GET_PROPERTY_INFO(port_info, DMPS_DB_CHAN_SPEED_MODE, speed_mode);

            CTC_ERROR_RETURN(_sys_tmg_datapath_set_qmgr_credit(lchip, chan_id, speed_mode));
        }
        else
        {
            CTC_ERROR_RETURN(_sys_tmg_datapath_set_qmgr_credit(lchip, chan_id, 0));
        }
    }

    return CTC_E_NONE;
}

/*br2EpeSch_sop_credit_sum > 1024*/
/*br2EpeSch_body_credit_sum > 768*/
/*QMsg buffer size > 512*/
/*EpeSch Credit > 256*/
int32
_sys_tmg_datapath_check_dp_credit(uint8 lchip, uint8 dp)
{
    ///TODO: tbd
    return CTC_E_NONE;
}

int32
_sys_tmg_check_datapath_credit_clear(uint8 lchip, uint32 mac_id, uint32 chan_id)
{
    uint32 cmd    = 0;
    uint32 index  = 0;
    uint32 credit = 0;
    uint32 cnt    = 0;
    uint32 tbl_id = 0;
    uint8  dp_id       = 0;
    uint8  dp_chan_id  = 0;
    uint8  dp_txqm_id  = 0;
    uint8  txqm_mac_id =  0;
    uint8  port_type   = 0;
    sys_dmps_db_upt_info_t port_info = {0};

    dp_id       = SYS_TMG_GET_DP_ID_FROM_CHANID(chan_id);
    dp_chan_id  = SYS_TMG_CHANNEL_TO_DPCHAN(chan_id);
    dp_txqm_id  = SYS_TMG_GET_DP_TXQM_BY_MAC_ID(mac_id);
    txqm_mac_id = SYS_TMG_GET_INNER_MAC_ID(mac_id);

    /* 1. check BufRetrvDPSopCreditMem.credit*/
    credit = 0;
    cnt    = 0;
    index  = DRV_INS(dp_id, dp_chan_id);
    cmd    = DRV_IOR(BufRetrvDPSopCreditMem_t, BufRetrvDPSopCreditMem_credit_f);
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, index, cmd, &credit));
    while(credit)
    {
#ifdef EMULATION_ENV
        sal_task_sleep(1000);
#else
        sal_task_sleep(20);
#endif
        if((cnt++) > 50)
        {
            SYS_DATAPATH_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, " BufRetrvDPSopCreditMem_credit (chan: %d) cannot return to Zero \n", 
                chan_id);
            return CTC_E_HW_FAIL;
        }
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, index, cmd, &credit));
    }

    /* 2. BufRetrvDPBodyCreditMem.credit*/
    credit = 0;
    cnt    = 0;
    index  = DRV_INS(dp_id, dp_chan_id);
    cmd    = DRV_IOR(BufRetrvDPBodyCreditMem_t, BufRetrvDPBodyCreditMem_credit_f);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &credit));
    while(credit)
    {
#ifdef EMULATION_ENV
        sal_task_sleep(1000);
#else
        sal_task_sleep(20);
#endif
        if((cnt++) > 50)
        {
            SYS_DATAPATH_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, " BufRetrvDPBodyCreditMem_credit (chan: %d) cannot return to Zero \n", 
                chan_id);
            return CTC_E_HW_FAIL;
        }
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, index, cmd, &credit));
    }

    SYS_CONDITION_RETURN(SYS_TMG_TXQM_NUM_PER_DP <= dp_txqm_id, CTC_E_NONE);

    /* 3. check NetTxCreditUsed0.creditUsed*/
    CTC_ERROR_RETURN(sys_usw_dmps_db_upt_info_init(lchip, &port_info));
    DMPS_DB_SET_MAP_INFO(port_info, DMPS_DB_MAC_ID, mac_id);
    DMPS_DB_SET_PROPERTY_UPDATE(port_info, DMPS_DB_PORT_TYPE);
    CTC_ERROR_RETURN(sys_usw_dmps_db_get_port_info(lchip, &port_info));
    DMPS_DB_GET_PROPERTY_INFO(port_info, DMPS_DB_PORT_TYPE, port_type);
        
    if (port_type != SYS_DMPS_NETWORK_PORT)
    {
        return CTC_E_NONE;
    }
    
    credit = 0;
    cnt    = 0;
    switch(dp_txqm_id)
    {
        case 0:
            tbl_id = NetTxCreditUsed0_t;
            break;
        case 1:
            tbl_id = NetTxCreditUsed1_t;
            break;
        case 2:
            tbl_id = NetTxCreditUsed2_t;
            break;
        case 3:
            tbl_id = NetTxCreditUsed3_t;
            break;
        case 4:
        default:
            tbl_id = NetTxCreditUsed4_t;
            break;
    }
    index = DRV_INS(dp_id, txqm_mac_id);
    cmd = DRV_IOR(tbl_id, NetTxCreditUsed0_creditUsed_f);
    CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, index, cmd, &credit));
    while(credit)
    {
#ifdef EMULATION_ENV
        sal_task_sleep(1000);
#else
        sal_task_sleep(20);
#endif
        if((cnt++) >50)
        {
            SYS_DATAPATH_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "NetTxCreditUsed%d_creditUsed cannot return to Zero, dp %u, txqm mac id %u \n", 
                dp_txqm_id, dp_id, txqm_mac_id);
            return CTC_E_HW_FAIL;
        }
        CTC_ERROR_RETURN(DRV_FIELD_IOCTL(lchip, index, cmd, &credit));
    }

    return CTC_E_NONE;
}

int32
_sys_tmg_datapath_init_dp(uint8 lchip, ctc_datapath_global_cfg_t* p_datapath_cfg)
{
    uint8  dp                        = 0;
    uint32 dp_txqm                   = 0;
    uint32 txqm_id                   = 0;
    sys_dmps_change_chan_info_t info = {0};

    for(dp = 0; dp < SYS_TMG_DP_NUM; dp++)
    {
        SYS_CONDITION_CONTINUE(!_sys_tmg_datapath_is_dp_in_use(lchip, dp));

        /*check bw/credit/calendar: qmgr, bufretrv, epe, nettx*/
        for(dp_txqm = 0; dp_txqm < SYS_TMG_TXQM_NUM_PER_DP; dp_txqm++)
        {
            CTC_ERROR_RETURN(_sys_tmg_datapath_check(lchip, dp, dp_txqm, &info, CHAN_DIR_TXRX, TRUE));
        }
    
        /*set Epe, NetRx, BufRetrv calendar*/
        CTC_ERROR_RETURN(_sys_tmg_datapath_set_general_calendar(lchip, dp));

        /*set nettx calendar*/
        for(dp_txqm = 0; dp_txqm < SYS_TMG_TXQM_NUM_PER_DP; dp_txqm++)
        {
            txqm_id = dp * SYS_TMG_TXQM_NUM_PER_DP + dp_txqm;
            SYS_CONDITION_CONTINUE(FALSE == _sys_tmg_datapath_is_txqm_in_use(lchip, txqm_id));
            CTC_ERROR_RETURN(_sys_tmg_datapath_set_nettx_calendar(lchip, dp, dp_txqm));
        }
        
        /*netrx: wrr weight*/
        CTC_ERROR_RETURN(_sys_tmg_datapath_set_dp_netrx_cfg(lchip, dp));

        /*bufretrv: credit, wrr weight*/
        CTC_ERROR_RETURN(_sys_tmg_datapath_bufretrv_init(lchip, dp));

        /*epe: credit, xglg en, wrr weight*/
        CTC_ERROR_RETURN(_sys_tmg_datapath_epe_init(lchip, dp));

        /*nettx: credit, txthrd, timerEn*/
        CTC_ERROR_RETURN(_sys_tmg_datapath_nettx_init(lchip, dp));

        /*qmgr: credit*/
        CTC_ERROR_RETURN(_sys_tmg_datapath_qmgr_crdt_init(lchip, dp));

        /*datapath map tables config, NW & MISC*/
        CTC_ERROR_RETURN(_sys_tmg_datapath_set_dp_map(lchip, dp));
    }

    /**/
    CTC_ERROR_RETURN(_sys_tmg_datapath_inter_dp_cfg(lchip));

    /**/
    CTC_ERROR_RETURN(_sys_tmg_datapath_static_init(lchip));

    return CTC_E_NONE;
}

STATIC int32
_sys_tmg_datapath_init_macpcs_power_down(uint8 lchip, ctc_datapath_global_cfg_t* p_datapath_cfg)
{
    return CTC_E_NONE;
}

STATIC int32
_sys_tmg_datapath_init_omitted_table(uint8 lchip)
{
    return CTC_E_NONE;
}

STATIC int32
_sys_tmg_datapath_init_pulse_cfg(uint8 lchip)
{
    uint32 cmd = 0;
    uint32 value = 0;
    RefDivCpuMacPulse_m  rd_cpumac;
    RefDivMcPcsLinkPulse_m rd_pcs;
    RefDivMcMacPulse_m   rd_mac;
    RefDivCoppUpdPulse_m rd_copp;
    RefDivDlbPulse_m     rd_dlb;
    RefDivEfdPulse_m     rd_efd;
    RefDivLagEnginePulse_m rd_lag;
    RefDivNetTxEeePulse_m rd_nettx;
    RefDivPolicingUpdPulse_m rd_plc;
    RefDivQMgrDeqShpPulse_m rd_qmgr;
    RefDivSpnOamTxPulse_m rd_spn;
    RefDivStormCtlUpdPulse_m rd_sto;

    /*RefDiv reset*/
    cmd = DRV_IOR(RefDivCpuMacPulse_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &rd_cpumac));
    value = 0;
    DRV_IOW_FIELD(lchip, RefDivCpuMacPulse_t, RefDivCpuMacPulse_cfgResetDivCpuMacHiBerPulse_f,  &value, &rd_cpumac);
    DRV_IOW_FIELD(lchip, RefDivCpuMacPulse_t, RefDivCpuMacPulse_cfgResetDivCpuMacLinkFilterPulse_f,  &value, &rd_cpumac);
    DRV_IOW_FIELD(lchip, RefDivCpuMacPulse_t, RefDivCpuMacPulse_cfgResetDivCpuMacLinkPulse_f,        &value, &rd_cpumac);
    DRV_IOW_FIELD(lchip, RefDivCpuMacPulse_t, RefDivCpuMacPulse_cfgResetDivCpuMacPauseLockPulse_f,   &value, &rd_cpumac);
    DRV_IOW_FIELD(lchip, RefDivCpuMacPulse_t, RefDivCpuMacPulse_cfgResetDivCpuMacPauseTimer0Pulse_f, &value, &rd_cpumac);
    DRV_IOW_FIELD(lchip, RefDivCpuMacPulse_t, RefDivCpuMacPulse_cfgResetDivCpuMacPauseTimer1Pulse_f, &value, &rd_cpumac);
    DRV_IOW_FIELD(lchip, RefDivCpuMacPulse_t, RefDivCpuMacPulse_cfgResetDivCpuMacPauseTimer2Pulse_f, &value, &rd_cpumac);
    DRV_IOW_FIELD(lchip, RefDivCpuMacPulse_t, RefDivCpuMacPulse_cfgResetDivCpuMacPauseTimer3Pulse_f, &value, &rd_cpumac);
    cmd = DRV_IOW(RefDivCpuMacPulse_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &rd_cpumac));

    cmd = DRV_IOR(RefDivMcPcsLinkPulse_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &rd_pcs));
    value = 0;
    DRV_IOW_FIELD(lchip, RefDivMcPcsLinkPulse_t, RefDivMcPcsLinkPulse_cfgResetDivMcMac0Dp0McPcsLinkPulse_f, &value, &rd_pcs);
    DRV_IOW_FIELD(lchip, RefDivMcPcsLinkPulse_t, RefDivMcPcsLinkPulse_cfgResetDivMcMac0Dp1McPcsLinkPulse_f, &value, &rd_pcs);
    DRV_IOW_FIELD(lchip, RefDivMcPcsLinkPulse_t, RefDivMcPcsLinkPulse_cfgResetDivMcMac1Dp0McPcsLinkPulse_f, &value, &rd_pcs);
    DRV_IOW_FIELD(lchip, RefDivMcPcsLinkPulse_t, RefDivMcPcsLinkPulse_cfgResetDivMcMac1Dp1McPcsLinkPulse_f, &value, &rd_pcs);
    DRV_IOW_FIELD(lchip, RefDivMcPcsLinkPulse_t, RefDivMcPcsLinkPulse_cfgResetDivMcMac2Dp0McPcsLinkPulse_f, &value, &rd_pcs);
    DRV_IOW_FIELD(lchip, RefDivMcPcsLinkPulse_t, RefDivMcPcsLinkPulse_cfgResetDivMcMac2Dp1McPcsLinkPulse_f, &value, &rd_pcs);
    DRV_IOW_FIELD(lchip, RefDivMcPcsLinkPulse_t, RefDivMcPcsLinkPulse_cfgResetDivMcMac3Dp0McPcsLinkPulse_f, &value, &rd_pcs);
    DRV_IOW_FIELD(lchip, RefDivMcPcsLinkPulse_t, RefDivMcPcsLinkPulse_cfgResetDivMcMac3Dp1McPcsLinkPulse_f, &value, &rd_pcs);
    DRV_IOW_FIELD(lchip, RefDivMcPcsLinkPulse_t, RefDivMcPcsLinkPulse_cfgResetDivMcMac4Dp0McPcsLinkPulse_f, &value, &rd_pcs);
    DRV_IOW_FIELD(lchip, RefDivMcPcsLinkPulse_t, RefDivMcPcsLinkPulse_cfgResetDivMcMac4Dp1McPcsLinkPulse_f, &value, &rd_pcs);
    cmd = DRV_IOW(RefDivMcPcsLinkPulse_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &rd_pcs));

    cmd = DRV_IOR(RefDivMcMacPulse_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &rd_mac));
    value = 0;
    DRV_IOW_FIELD(lchip, RefDivMcMacPulse_t, RefDivMcMacPulse_cfgResetDivMcMac0Dp0LinkFilterPulse_f,       &value, &rd_mac);
    DRV_IOW_FIELD(lchip, RefDivMcMacPulse_t, RefDivMcMacPulse_cfgResetDivMcMac0Dp0SgmacPauseLockPulse_f,   &value, &rd_mac);
    DRV_IOW_FIELD(lchip, RefDivMcMacPulse_t, RefDivMcMacPulse_cfgResetDivMcMac0Dp0SgmacPauseTimer0Pulse_f, &value, &rd_mac);
    DRV_IOW_FIELD(lchip, RefDivMcMacPulse_t, RefDivMcMacPulse_cfgResetDivMcMac0Dp0SgmacPauseTimer1Pulse_f, &value, &rd_mac);
    DRV_IOW_FIELD(lchip, RefDivMcMacPulse_t, RefDivMcMacPulse_cfgResetDivMcMac0Dp0SgmacPauseTimer2Pulse_f, &value, &rd_mac);
    DRV_IOW_FIELD(lchip, RefDivMcMacPulse_t, RefDivMcMacPulse_cfgResetDivMcMac0Dp0SgmacPauseTimer3Pulse_f, &value, &rd_mac);
    DRV_IOW_FIELD(lchip, RefDivMcMacPulse_t, RefDivMcMacPulse_cfgResetDivMcMac0Dp1LinkFilterPulse_f,       &value, &rd_mac);
    DRV_IOW_FIELD(lchip, RefDivMcMacPulse_t, RefDivMcMacPulse_cfgResetDivMcMac0Dp1SgmacPauseLockPulse_f,   &value, &rd_mac);
    DRV_IOW_FIELD(lchip, RefDivMcMacPulse_t, RefDivMcMacPulse_cfgResetDivMcMac0Dp1SgmacPauseTimer0Pulse_f, &value, &rd_mac);
    DRV_IOW_FIELD(lchip, RefDivMcMacPulse_t, RefDivMcMacPulse_cfgResetDivMcMac0Dp1SgmacPauseTimer1Pulse_f, &value, &rd_mac);
    DRV_IOW_FIELD(lchip, RefDivMcMacPulse_t, RefDivMcMacPulse_cfgResetDivMcMac0Dp1SgmacPauseTimer2Pulse_f, &value, &rd_mac);
    DRV_IOW_FIELD(lchip, RefDivMcMacPulse_t, RefDivMcMacPulse_cfgResetDivMcMac0Dp1SgmacPauseTimer3Pulse_f, &value, &rd_mac);
    DRV_IOW_FIELD(lchip, RefDivMcMacPulse_t, RefDivMcMacPulse_cfgResetDivMcMac1Dp0LinkFilterPulse_f,       &value, &rd_mac);
    DRV_IOW_FIELD(lchip, RefDivMcMacPulse_t, RefDivMcMacPulse_cfgResetDivMcMac1Dp0SgmacPauseLockPulse_f,   &value, &rd_mac);
    DRV_IOW_FIELD(lchip, RefDivMcMacPulse_t, RefDivMcMacPulse_cfgResetDivMcMac1Dp0SgmacPauseTimer0Pulse_f, &value, &rd_mac);
    DRV_IOW_FIELD(lchip, RefDivMcMacPulse_t, RefDivMcMacPulse_cfgResetDivMcMac1Dp0SgmacPauseTimer1Pulse_f, &value, &rd_mac);
    DRV_IOW_FIELD(lchip, RefDivMcMacPulse_t, RefDivMcMacPulse_cfgResetDivMcMac1Dp0SgmacPauseTimer2Pulse_f, &value, &rd_mac);
    DRV_IOW_FIELD(lchip, RefDivMcMacPulse_t, RefDivMcMacPulse_cfgResetDivMcMac1Dp0SgmacPauseTimer3Pulse_f, &value, &rd_mac);
    DRV_IOW_FIELD(lchip, RefDivMcMacPulse_t, RefDivMcMacPulse_cfgResetDivMcMac1Dp1LinkFilterPulse_f,       &value, &rd_mac);
    DRV_IOW_FIELD(lchip, RefDivMcMacPulse_t, RefDivMcMacPulse_cfgResetDivMcMac1Dp1SgmacPauseLockPulse_f,   &value, &rd_mac);
    DRV_IOW_FIELD(lchip, RefDivMcMacPulse_t, RefDivMcMacPulse_cfgResetDivMcMac1Dp1SgmacPauseTimer0Pulse_f, &value, &rd_mac);
    DRV_IOW_FIELD(lchip, RefDivMcMacPulse_t, RefDivMcMacPulse_cfgResetDivMcMac1Dp1SgmacPauseTimer1Pulse_f, &value, &rd_mac);
    DRV_IOW_FIELD(lchip, RefDivMcMacPulse_t, RefDivMcMacPulse_cfgResetDivMcMac1Dp1SgmacPauseTimer2Pulse_f, &value, &rd_mac);
    DRV_IOW_FIELD(lchip, RefDivMcMacPulse_t, RefDivMcMacPulse_cfgResetDivMcMac1Dp1SgmacPauseTimer3Pulse_f, &value, &rd_mac);
    DRV_IOW_FIELD(lchip, RefDivMcMacPulse_t, RefDivMcMacPulse_cfgResetDivMcMac2Dp0LinkFilterPulse_f,       &value, &rd_mac);
    DRV_IOW_FIELD(lchip, RefDivMcMacPulse_t, RefDivMcMacPulse_cfgResetDivMcMac2Dp0SgmacPauseLockPulse_f,   &value, &rd_mac);
    DRV_IOW_FIELD(lchip, RefDivMcMacPulse_t, RefDivMcMacPulse_cfgResetDivMcMac2Dp0SgmacPauseTimer0Pulse_f, &value, &rd_mac);
    DRV_IOW_FIELD(lchip, RefDivMcMacPulse_t, RefDivMcMacPulse_cfgResetDivMcMac2Dp0SgmacPauseTimer1Pulse_f, &value, &rd_mac);
    DRV_IOW_FIELD(lchip, RefDivMcMacPulse_t, RefDivMcMacPulse_cfgResetDivMcMac2Dp0SgmacPauseTimer2Pulse_f, &value, &rd_mac);
    DRV_IOW_FIELD(lchip, RefDivMcMacPulse_t, RefDivMcMacPulse_cfgResetDivMcMac2Dp0SgmacPauseTimer3Pulse_f, &value, &rd_mac);
    DRV_IOW_FIELD(lchip, RefDivMcMacPulse_t, RefDivMcMacPulse_cfgResetDivMcMac2Dp1LinkFilterPulse_f,       &value, &rd_mac);
    DRV_IOW_FIELD(lchip, RefDivMcMacPulse_t, RefDivMcMacPulse_cfgResetDivMcMac2Dp1SgmacPauseLockPulse_f,   &value, &rd_mac);
    DRV_IOW_FIELD(lchip, RefDivMcMacPulse_t, RefDivMcMacPulse_cfgResetDivMcMac2Dp1SgmacPauseTimer0Pulse_f, &value, &rd_mac);
    DRV_IOW_FIELD(lchip, RefDivMcMacPulse_t, RefDivMcMacPulse_cfgResetDivMcMac2Dp1SgmacPauseTimer1Pulse_f, &value, &rd_mac);
    DRV_IOW_FIELD(lchip, RefDivMcMacPulse_t, RefDivMcMacPulse_cfgResetDivMcMac2Dp1SgmacPauseTimer2Pulse_f, &value, &rd_mac);
    DRV_IOW_FIELD(lchip, RefDivMcMacPulse_t, RefDivMcMacPulse_cfgResetDivMcMac2Dp1SgmacPauseTimer3Pulse_f, &value, &rd_mac);
    DRV_IOW_FIELD(lchip, RefDivMcMacPulse_t, RefDivMcMacPulse_cfgResetDivMcMac3Dp0LinkFilterPulse_f,       &value, &rd_mac);
    DRV_IOW_FIELD(lchip, RefDivMcMacPulse_t, RefDivMcMacPulse_cfgResetDivMcMac3Dp0SgmacPauseLockPulse_f,   &value, &rd_mac);
    DRV_IOW_FIELD(lchip, RefDivMcMacPulse_t, RefDivMcMacPulse_cfgResetDivMcMac3Dp0SgmacPauseTimer0Pulse_f, &value, &rd_mac);
    DRV_IOW_FIELD(lchip, RefDivMcMacPulse_t, RefDivMcMacPulse_cfgResetDivMcMac3Dp0SgmacPauseTimer1Pulse_f, &value, &rd_mac);
    DRV_IOW_FIELD(lchip, RefDivMcMacPulse_t, RefDivMcMacPulse_cfgResetDivMcMac3Dp0SgmacPauseTimer2Pulse_f, &value, &rd_mac);
    DRV_IOW_FIELD(lchip, RefDivMcMacPulse_t, RefDivMcMacPulse_cfgResetDivMcMac3Dp0SgmacPauseTimer3Pulse_f, &value, &rd_mac);
    DRV_IOW_FIELD(lchip, RefDivMcMacPulse_t, RefDivMcMacPulse_cfgResetDivMcMac3Dp1LinkFilterPulse_f,       &value, &rd_mac);
    DRV_IOW_FIELD(lchip, RefDivMcMacPulse_t, RefDivMcMacPulse_cfgResetDivMcMac3Dp1SgmacPauseLockPulse_f,   &value, &rd_mac);
    DRV_IOW_FIELD(lchip, RefDivMcMacPulse_t, RefDivMcMacPulse_cfgResetDivMcMac3Dp1SgmacPauseTimer0Pulse_f, &value, &rd_mac);
    DRV_IOW_FIELD(lchip, RefDivMcMacPulse_t, RefDivMcMacPulse_cfgResetDivMcMac3Dp1SgmacPauseTimer1Pulse_f, &value, &rd_mac);
    DRV_IOW_FIELD(lchip, RefDivMcMacPulse_t, RefDivMcMacPulse_cfgResetDivMcMac3Dp1SgmacPauseTimer2Pulse_f, &value, &rd_mac);
    DRV_IOW_FIELD(lchip, RefDivMcMacPulse_t, RefDivMcMacPulse_cfgResetDivMcMac3Dp1SgmacPauseTimer3Pulse_f, &value, &rd_mac);
    DRV_IOW_FIELD(lchip, RefDivMcMacPulse_t, RefDivMcMacPulse_cfgResetDivMcMac4Dp0LinkFilterPulse_f,       &value, &rd_mac);
    DRV_IOW_FIELD(lchip, RefDivMcMacPulse_t, RefDivMcMacPulse_cfgResetDivMcMac4Dp0SgmacPauseLockPulse_f,   &value, &rd_mac);
    DRV_IOW_FIELD(lchip, RefDivMcMacPulse_t, RefDivMcMacPulse_cfgResetDivMcMac4Dp0SgmacPauseTimer0Pulse_f, &value, &rd_mac);
    DRV_IOW_FIELD(lchip, RefDivMcMacPulse_t, RefDivMcMacPulse_cfgResetDivMcMac4Dp0SgmacPauseTimer1Pulse_f, &value, &rd_mac);
    DRV_IOW_FIELD(lchip, RefDivMcMacPulse_t, RefDivMcMacPulse_cfgResetDivMcMac4Dp0SgmacPauseTimer2Pulse_f, &value, &rd_mac);
    DRV_IOW_FIELD(lchip, RefDivMcMacPulse_t, RefDivMcMacPulse_cfgResetDivMcMac4Dp0SgmacPauseTimer3Pulse_f, &value, &rd_mac);
    DRV_IOW_FIELD(lchip, RefDivMcMacPulse_t, RefDivMcMacPulse_cfgResetDivMcMac4Dp1LinkFilterPulse_f,       &value, &rd_mac);
    DRV_IOW_FIELD(lchip, RefDivMcMacPulse_t, RefDivMcMacPulse_cfgResetDivMcMac4Dp1SgmacPauseLockPulse_f,   &value, &rd_mac);
    DRV_IOW_FIELD(lchip, RefDivMcMacPulse_t, RefDivMcMacPulse_cfgResetDivMcMac4Dp1SgmacPauseTimer0Pulse_f, &value, &rd_mac);
    DRV_IOW_FIELD(lchip, RefDivMcMacPulse_t, RefDivMcMacPulse_cfgResetDivMcMac4Dp1SgmacPauseTimer1Pulse_f, &value, &rd_mac);
    DRV_IOW_FIELD(lchip, RefDivMcMacPulse_t, RefDivMcMacPulse_cfgResetDivMcMac4Dp1SgmacPauseTimer2Pulse_f, &value, &rd_mac);
    DRV_IOW_FIELD(lchip, RefDivMcMacPulse_t, RefDivMcMacPulse_cfgResetDivMcMac4Dp1SgmacPauseTimer3Pulse_f, &value, &rd_mac);

    DRV_IOW_FIELD(lchip, RefDivMcMacPulse_t, RefDivMcMacPulse_cfgResetDivMcMac0Dp0HiBerPulse_f, &value, &rd_mac);
    DRV_IOW_FIELD(lchip, RefDivMcMacPulse_t, RefDivMcMacPulse_cfgResetDivMcMac0Dp1HiBerPulse_f, &value, &rd_mac);
    DRV_IOW_FIELD(lchip, RefDivMcMacPulse_t, RefDivMcMacPulse_cfgResetDivMcMac1Dp0HiBerPulse_f, &value, &rd_mac);
    DRV_IOW_FIELD(lchip, RefDivMcMacPulse_t, RefDivMcMacPulse_cfgResetDivMcMac1Dp1HiBerPulse_f, &value, &rd_mac);
    DRV_IOW_FIELD(lchip, RefDivMcMacPulse_t, RefDivMcMacPulse_cfgResetDivMcMac2Dp0HiBerPulse_f, &value, &rd_mac);
    DRV_IOW_FIELD(lchip, RefDivMcMacPulse_t, RefDivMcMacPulse_cfgResetDivMcMac2Dp1HiBerPulse_f, &value, &rd_mac);
    DRV_IOW_FIELD(lchip, RefDivMcMacPulse_t, RefDivMcMacPulse_cfgResetDivMcMac3Dp0HiBerPulse_f, &value, &rd_mac);
    DRV_IOW_FIELD(lchip, RefDivMcMacPulse_t, RefDivMcMacPulse_cfgResetDivMcMac3Dp1HiBerPulse_f, &value, &rd_mac);
    DRV_IOW_FIELD(lchip, RefDivMcMacPulse_t, RefDivMcMacPulse_cfgResetDivMcMac4Dp0HiBerPulse_f, &value, &rd_mac);
    DRV_IOW_FIELD(lchip, RefDivMcMacPulse_t, RefDivMcMacPulse_cfgResetDivMcMac4Dp1HiBerPulse_f, &value, &rd_mac);

    cmd = DRV_IOW(RefDivMcMacPulse_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &rd_mac));

    cmd = DRV_IOR(RefDivCoppUpdPulse_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &rd_copp));
    value = 0;
    DRV_IOW_FIELD(lchip, RefDivCoppUpdPulse_t, RefDivCoppUpdPulse_cfgResetDivCoppEpeUpdPulse_f,  &value, &rd_copp);
    DRV_IOW_FIELD(lchip, RefDivCoppUpdPulse_t, RefDivCoppUpdPulse_cfgResetDivCoppIpeUpdPulse_f,  &value, &rd_copp);
    cmd = DRV_IOW(RefDivCoppUpdPulse_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &rd_copp));

    cmd = DRV_IOR(RefDivDlbPulse_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &rd_dlb));
    value = 0;
    DRV_IOW_FIELD(lchip, RefDivDlbPulse_t, RefDivDlbPulse_cfgResetDivDlbPulse_f,  &value, &rd_dlb);
    cmd = DRV_IOW(RefDivDlbPulse_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &rd_dlb));

    cmd = DRV_IOR(RefDivEfdPulse_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &rd_efd));
    value = 0;
    DRV_IOW_FIELD(lchip, RefDivEfdPulse_t, RefDivEfdPulse_cfgResetDivEfdPulse_f,  &value, &rd_efd);
    cmd = DRV_IOW(RefDivEfdPulse_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &rd_efd));

    cmd = DRV_IOR(RefDivLagEnginePulse_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &rd_lag));
    value = 0;
    DRV_IOW_FIELD(lchip, RefDivLagEnginePulse_t, RefDivLagEnginePulse_cfgResetDivLagEngineChanAvgLoadPulse_f,         &value, &rd_lag);
    DRV_IOW_FIELD(lchip, RefDivLagEnginePulse_t, RefDivLagEnginePulse_cfgResetDivLagEngineChanAvgQSizePulse_f,        &value, &rd_lag);
    DRV_IOW_FIELD(lchip, RefDivLagEnginePulse_t, RefDivLagEnginePulse_cfgResetDivLagEngineFlowSetActiveUpdatePulse_f, &value, &rd_lag);
    cmd = DRV_IOW(RefDivLagEnginePulse_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &rd_lag));

    cmd = DRV_IOR(RefDivNetTxEeePulse_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &rd_nettx));
    value = 0;
    DRV_IOW_FIELD(lchip, RefDivNetTxEeePulse_t, RefDivNetTxEeePulse_cfgResetDivSlice0Dp0NetTxEeePulse_f,  &value, &rd_nettx);
    DRV_IOW_FIELD(lchip, RefDivNetTxEeePulse_t, RefDivNetTxEeePulse_cfgResetDivSlice0Dp1NetTxEeePulse_f,  &value, &rd_nettx);
    cmd = DRV_IOW(RefDivNetTxEeePulse_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &rd_nettx));

    cmd = DRV_IOR(RefDivPolicingUpdPulse_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &rd_plc));
    value = 0;
    DRV_IOW_FIELD(lchip, RefDivPolicingUpdPulse_t, RefDivPolicingUpdPulse_cfgResetDivEpePolicing0UpdPulse_f, &value, &rd_plc);
    DRV_IOW_FIELD(lchip, RefDivPolicingUpdPulse_t, RefDivPolicingUpdPulse_cfgResetDivEpePolicing1UpdPulse_f, &value, &rd_plc);
    DRV_IOW_FIELD(lchip, RefDivPolicingUpdPulse_t, RefDivPolicingUpdPulse_cfgResetDivIpePolicing0UpdPulse_f, &value, &rd_plc);
    DRV_IOW_FIELD(lchip, RefDivPolicingUpdPulse_t, RefDivPolicingUpdPulse_cfgResetDivIpePolicing1UpdPulse_f, &value, &rd_plc);
    DRV_IOW_FIELD(lchip, RefDivPolicingUpdPulse_t, RefDivPolicingUpdPulse_cfgResetDivSvcPolicingUpdPulse_f,  &value, &rd_plc);
    cmd = DRV_IOW(RefDivPolicingUpdPulse_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &rd_plc));

    cmd = DRV_IOR(RefDivQMgrDeqShpPulse_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &rd_qmgr));
    value = 0;
    DRV_IOW_FIELD(lchip, RefDivQMgrDeqShpPulse_t, RefDivQMgrDeqShpPulse_cfgResetDivQMgrDeqShpPulse_f,  &value, &rd_qmgr);
    cmd = DRV_IOW(RefDivQMgrDeqShpPulse_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &rd_qmgr));

    cmd = DRV_IOR(RefDivSpnOamTxPulse_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &rd_spn));
    value = 0;
    DRV_IOW_FIELD(lchip, RefDivSpnOamTxPulse_t, RefDivSpnOamTxPulse_cfgResetDivSpnOamTxPulse_f,  &value, &rd_spn);
    cmd = DRV_IOW(RefDivSpnOamTxPulse_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &rd_spn));

    cmd = DRV_IOR(RefDivStormCtlUpdPulse_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &rd_sto));
    value = 0;
    DRV_IOW_FIELD(lchip, RefDivStormCtlUpdPulse_t, RefDivStormCtlUpdPulse_cfgResetDivStormCtl0UpdPulse_f,  &value, &rd_sto);
    DRV_IOW_FIELD(lchip, RefDivStormCtlUpdPulse_t, RefDivStormCtlUpdPulse_cfgResetDivStormCtl1UpdPulse_f,  &value, &rd_sto);
    cmd = DRV_IOW(RefDivStormCtlUpdPulse_t, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, 0, cmd, &rd_sto));

    return CTC_E_NONE;
}


#endif

uint32 
_sys_tmg_datapath_get_serdes_support_speed_bmp(uint8 lchip, uint16 logical_serdes)
{
    uint8  len       = 0;
    uint8  idx       = 0;
    uint32 speed_bmp = 0;
    uint8 tmg_serdes_speed_list[] = 
    {
        SERDES_SPEED_0G       ,          /* serdes_speed = 0,         ock = CTC_CHIP_SERDES_OCS_MODE_NONE */            
        SERDES_SPEED_1_25G    ,          /* serdes_speed = 1250000,   ock = CTC_CHIP_SERDES_OCS_MODE_NONE */
        SERDES_SPEED_3_125G   ,          /* serdes_speed = 3125000,   ock = CTC_CHIP_SERDES_OCS_MODE_NONE */
        SERDES_SPEED_10_3125G ,          /* serdes_speed = 10312500,  ock = CTC_CHIP_SERDES_OCS_MODE_NONE */
        SERDES_SPEED_25_78125G,          /* serdes_speed = 25781250,  ock = CTC_CHIP_SERDES_OCS_MODE_NONE */
        SERDES_SPEED_26_5625G ,          /* serdes_speed = 26562500,  ock = CTC_CHIP_SERDES_OCS_MODE_26_56G */   
        SERDES_SPEED_12_96875G,          /* serdes_speed = 12968750,  ock = CTC_CHIP_SERDES_OCS_MODE_12_58G */
        SERDES_SPEED_28_125G,            /* serdes_speed = 28125000,  ock = CTC_CHIP_SERDES_OCS_MODE_27_27G */
        SERDES_SPEED_10_9375G,           /* serdes_speed = 10937500,  ock = CTC_CHIP_SERDES_OCS_MODE_10_6G */
        SERDES_SPEED_12_5G,              /* serdes_speed = 12500000,  ock = CTC_CHIP_SERDES_OCS_MODE_12_12G */
        SERDES_SPEED_27_34375G,          /* serdes_speed = 27343750,  ock = CTC_CHIP_SERDES_OCS_MODE_26_52G */      
        SERDES_SPEED_11_40625G,          /* serdes_speed = 11406250,  ock = CTC_CHIP_SERDES_OCS_MODE_11_06G */
        SERDES_SPEED_27_78125G,          /* serdes_speed = 27781250,  ock = CTC_CHIP_SERDES_OCS_MODE_26_9G */   
    };

    len = sizeof(tmg_serdes_speed_list)/sizeof(tmg_serdes_speed_list[0]);

    for (idx = 0; idx < len; idx ++)
    {
        speed_bmp |= (1 << tmg_serdes_speed_list[idx]);
    }

    return speed_bmp;
}

int32
_sys_tmg_datapath_init_chan_2_logic_serdes_map(uint8 lchip, ctc_datapath_global_cfg_t* p_cfg)
{
    uint8  dp                 = 0;
    uint8  lane_num           = 0;
    uint16 lsd                = 0;
    uint16 lsd_dp             = 0;
    uint16 chan_idx           = 0;
    uint16 sub_chan           = 0;
    uint16 lport              = 0;
    uint16 dport              = 0;
    uint8  occupy_flag        = 0;
    uint16 port_type          = 0;
    uint16 chan_dp[SYS_TMG_DP_NUM] = {0};
    sys_dmps_db_upt_info_t port_info          = {0};
    ctc_datapath_serdes_prop_t*  p_serdes_cfg = NULL;

    for(lsd = 0; lsd < SYS_TMG_MAX_SERDES_NUM; lsd++)
    {
        /*NW*/
        if(lsd < SYS_TMG_MAX_SERDES_NUM_NW)
        {
            dp      = lsd / SYS_TMG_MAX_SERDES_NUM_PER_DP;        
            lsd_dp  = lsd % SYS_TMG_MAX_SERDES_NUM_PER_DP;
            chan_idx = g_dmps_map_tmg[lsd].dp_id * SYS_TMG_CHANNEL_NUM_PER_DP + chan_dp[dp];
            sub_chan = chan_dp[dp];
            port_type = SYS_DMPS_NETWORK_PORT;
        }
        /*CPUMAC*/
        else
        {
            dp      = (lsd - SYS_TMG_MAX_SERDES_NUM_NW) / SYS_TMG_CPUMAC_NUM_PER_DP;
            lsd_dp  = (lsd - SYS_TMG_MAX_SERDES_NUM_NW) % SYS_TMG_CPUMAC_NUM_PER_DP;

            if(dp == 0)
            {
                chan_idx = (p_cfg->cpumac_dp0_network_en) ? chan_dp[0] : MCHIP_CAP(SYS_CAP_CHANID_CPU_MAC0 + lsd_dp);
                sub_chan = chan_idx % SYS_TMG_CHANNEL_NUM_PER_DP;
                port_type = (p_cfg->cpumac_dp0_network_en) ? SYS_DMPS_CPUMAC_NETWORK_PORT : SYS_DMPS_CPU_MAC_PORT;
            }
            else 
            {
                chan_idx = (p_cfg->cpumac_dp1_network_en) ? SYS_TMG_CHANNEL_NUM_PER_DP + chan_dp[1] : MCHIP_CAP(SYS_CAP_CHANID_CPU_MAC2 + lsd_dp);               
                sub_chan = chan_idx % SYS_TMG_CHANNEL_NUM_PER_DP;
                port_type = (p_cfg->cpumac_dp1_network_en) ? SYS_DMPS_CPUMAC_NETWORK_PORT : SYS_DMPS_CPU_MAC_PORT;
            }
        }
        
        p_serdes_cfg = &(p_cfg->serdes[lsd]);
        SYS_CONDITION_CONTINUE(NULL == p_serdes_cfg);
        
        if(SYS_SERDES_DYN_FORBID_ALL == p_serdes_cfg->is_dynamic)
        {
            SYS_TMG_GET_LANE_NUM_BY_MODE(p_serdes_cfg->mode, lane_num);
            SYS_CONDITION_CONTINUE(0 == lane_num);
            SYS_CONDITION_CONTINUE(0 != lsd_dp % lane_num);
        }

        /*if chan_idx is out of bound || the slot is not empty, skip*/
        CTC_ERROR_RETURN(sys_usw_dmps_db_get_chan2lsd(lchip, 0, chan_idx, &occupy_flag, NULL, NULL));
        SYS_CONDITION_CONTINUE(SYS_DP_CHAN_LPORT_OCCUPY_RSV != occupy_flag);

        /* alloc new chan in g_chan_2_logic_serdes_map */
        CTC_ERROR_RETURN(sys_usw_dmps_db_set_chan2lsd(lchip, 0, chan_idx, SYS_DP_CHAN_LPORT_OCCUPY_IN_USE, lsd, dport));

        /*init lport-dport map*/
        CTC_ERROR_RETURN(sys_usw_dmps_db_set_ext_lport_map(lchip, lport, dport));
        
        CTC_ERROR_RETURN(sys_usw_dmps_db_upt_info_init(lchip, &port_info));
        DMPS_DB_SET_MAP_INFO(port_info, DMPS_DB_DPORT,                      dport);
        DMPS_DB_SET_MAP_INFO(port_info, DMPS_DB_CHAN_ID,                    chan_idx);
        DMPS_DB_SET_MAP_INFO(port_info, DMPS_DB_CHAN_RX_ID,                 chan_idx);
        DMPS_DB_SET_PROPERTY_INFO(port_info, DMPS_DB_PORT_TYPE,             port_type);
        DMPS_DB_SET_PROPERTY_INFO(port_info, DMPS_DB_PORT_IS_RSV,           TRUE);
        DMPS_DB_SET_PROPERTY_INFO(port_info, DMPS_DB_CHAN_DP_ID,            g_dmps_map_tmg[lsd].dp_id);
        DMPS_DB_SET_PROPERTY_INFO(port_info, DMPS_DB_CHAN_TXQM_ID,          g_dmps_map_tmg[lsd].txqm_id);
        DMPS_DB_SET_PROPERTY_INFO(port_info, DMPS_DB_CHAN_MAC_CLIENT_ID,    g_dmps_map_tmg[lsd].mac_client);
        DMPS_DB_SET_PROPERTY_INFO(port_info, DMPS_DB_CHAN_SUB_CHAN_ID,      sub_chan);
        DMPS_DB_SET_PROPERTY_INFO(port_info, DMPS_DB_CHAN_PRIO,             0);
        DMPS_DB_SET_PROPERTY_INFO(port_info, DMPS_DB_CHAN_IS_RSV,           TRUE);
        DMPS_DB_SET_PROPERTY_INFO(port_info, DMPS_DB_CHAN_RX_CORE_ID,       0);
        DMPS_DB_SET_PROPERTY_INFO(port_info, DMPS_DB_CHAN_RX_DP_ID,         g_dmps_map_tmg[lsd].dp_id);
        DMPS_DB_SET_PROPERTY_INFO(port_info, DMPS_DB_CHAN_RX_TXQM_ID,       g_dmps_map_tmg[lsd].txqm_id);
        DMPS_DB_SET_PROPERTY_INFO(port_info, DMPS_DB_CHAN_RX_MAC_CLIENT_ID, g_dmps_map_tmg[lsd].mac_client);
        DMPS_DB_SET_PROPERTY_INFO(port_info, DMPS_DB_CHAN_RX_SUB_CHAN_ID,   sub_chan);
        DMPS_DB_SET_PROPERTY_INFO(port_info, DMPS_DB_CHAN_RX_PRIO,          0);
        DMPS_DB_SET_PROPERTY_INFO(port_info, DMPS_DB_CHAN_RX_IS_RSV,        TRUE);
        CTC_ERROR_RETURN(sys_usw_dmps_db_set_port_info(lchip, &port_info));
        
        /* opf: Assign channel and port */
        CTC_ERROR_RETURN(sys_usw_dmps_db_assign_chan(lchip, chan_idx));
        CTC_ERROR_RETURN(sys_usw_dmps_db_assign_port(lchip, lport));
        
        chan_dp[dp]++;
        dport++;
        lport = dport;
    }

    SYS_INTERNAL_PORT_START = lport;

    return CTC_E_NONE;
}

int32
_sys_tmg_datapath_init_mapping(uint8 lchip, ctc_datapath_global_cfg_t* p_cfg)
{   
    //uint8 idx                 = 0;
    //uint8 port_num            = 0;
    uint8  pcs_l              = 0;
    uint8  mac_group_id       = 0;
    uint8  mac_idx            = 0;
    uint8  pcs_idx            = 0;
    uint8  if_mode            = CTC_CHIP_MAX_SERDES_MODE;
    uint8  logic_lane         = 0;
    uint8  lane_num           = 0;
    uint8  fec_type           = SYS_DMPS_FEC_TYPE_NONE;
    uint8  if_type            = 0;
    uint8  port_type          = 0;
    uint8  speed_mode         = 0;
    uint8  physic_lane_id     = 0;
    uint8  is_occupy          = TRUE;
    uint16 mac_id             = 0;
    uint16 pcs_id             = 0;
    uint16 dport              = 0;
    uint16 dport_prv          = DMPS_INVALID_VALUE_U16;
    uint16 chan_prv           = DMPS_INVALID_VALUE_U16;
    uint16 chan_id            = 0;
    uint16 logic_serdes       = 0;
    uint16 physic_serdes      = 0;
    uint32 support_speed      = 0;
    uint32 serdes_speed       = 0;
    sys_dmps_serdes_speed_t  speed            = 0;
    sys_dmps_db_upt_info_t   port_info        = {0};
    sys_dmps_db_upt_info_t   port_info_p      = {0};
    sys_dmps_db_cpumac_map_t p_map            = {0};
    ctc_datapath_serdes_prop_t*  p_serdes_cfg = NULL;

    /* NetWork & CPUMAC database init */
    for (logic_serdes = 0; logic_serdes < SYS_TMG_MAX_SERDES_NUM; logic_serdes++)
    {
        /*skip invalid lanes*/
        p_serdes_cfg    = &(p_cfg->serdes[logic_serdes]);
        SYS_CONDITION_CONTINUE(NULL == p_serdes_cfg);

        p_map.lport      = DMPS_INVALID_VALUE_U16;
        p_map.is_network = FALSE;

        /* get chan and lport by logical serdes id */
        (void) _sys_tmg_datapath_get_lport_chan_by_serdes(lchip, logic_serdes, &chan_id, &dport);
        if ((chan_id >= DMPS_MAX_CHAN_NUM) || (dport >= DMPS_MAX_PORT_NUM))
        {
            is_occupy = FALSE;
        }
        else
        {
            is_occupy = TRUE;
        }

        CTC_ERROR_RETURN(sys_usw_dmps_db_upt_info_init(lchip, &port_info));

        /*info collection*/
        if_mode       = p_serdes_cfg->mode;
        if_mode       = (SYS_TMG_IS_MODE_NONE(if_mode)) ? CTC_CHIP_SERDES_NONE_MODE : if_mode;
        fec_type     = SYS_DMPS_IS_PAM4_MODE(if_mode) ? SYS_DMPS_FEC_TYPE_RS544 : SYS_DMPS_FEC_TYPE_NONE;
        SYS_TMG_GET_LANE_NUM_BY_MODE(if_mode, lane_num);
        logic_lane    = SYS_TMG_GET_INNER_LANE_BY_SERDES(logic_serdes);
        physic_serdes = p_serdes_cfg->physical_serdes_id;
        if ((SYS_DMPS_INVALID_U16 == physic_serdes) ||
            ((SYS_SERDES_DYN_FORBID_ALL == p_serdes_cfg->is_dynamic) && (0 == lane_num)))
        {
            continue;
        }

        switch (logic_serdes)
        {
            case 80:
            case 81:
                p_map.is_network = p_cfg->cpumac_dp0_network_en ? TRUE : FALSE;
                port_type = p_cfg->cpumac_dp0_network_en ? SYS_DMPS_CPUMAC_NETWORK_PORT : SYS_DMPS_CPU_MAC_PORT;
                break;
            case 82:
            case 83:
                p_map.is_network = p_cfg->cpumac_dp1_network_en ? TRUE : FALSE;
                port_type = p_cfg->cpumac_dp0_network_en ? SYS_DMPS_CPUMAC_NETWORK_PORT : SYS_DMPS_CPU_MAC_PORT;
                break;
            default:
                port_type = SYS_DMPS_NETWORK_PORT;
                break;
        }
        /* LOGIC SERDES DB */
        DMPS_DB_SET_PROPERTY_INFO(port_info, DMPS_DB_LSD_LANE_ID,  logic_lane);
        DMPS_DB_SET_PROPERTY_INFO(port_info, DMPS_DB_LSD_PCSL_IDX, ((0 == lane_num) ? 0 : logic_serdes % lane_num));
        DMPS_DB_SET_PROPERTY_INFO(port_info, DMPS_DB_LSD_HSS_ID,   SYS_TMG_GET_HSS_ID_BY_SERDES(logic_serdes));
        
        /* PHYSIC SERDES DB */
        physic_lane_id = SYS_TMG_GET_INNER_LANE_BY_SERDES(physic_serdes);
        support_speed  = _sys_tmg_datapath_get_serdes_support_speed_bmp(lchip, logic_serdes);
        speed          = sys_usw_dmps_get_speed_from_serdes_info(if_mode, fec_type, CTC_CHIP_SERDES_OCS_MODE_NONE);
        if (!((1 << speed) & support_speed))
        {
            SYS_DATAPATH_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, " %% Serdes %d cannot support speed %d!\n", physic_serdes, speed);
            return CTC_E_INVALID_CONFIG;
        }
        SYS_USW_SERDES_SPEED_2_VALUE(speed, serdes_speed);
        
        DMPS_DB_SET_PROPERTY_INFO(port_info, DMPS_DB_PSD_IS_DYN,   p_serdes_cfg->is_dynamic);
        DMPS_DB_SET_PROPERTY_INFO(port_info, DMPS_DB_PSD_PLL_SEL,       0);
        DMPS_DB_SET_PROPERTY_INFO(port_info, DMPS_DB_PSD_RATE_DIV,      0);
        DMPS_DB_SET_PROPERTY_INFO(port_info, DMPS_DB_PSD_BIT_WIDTH,     0);
        DMPS_DB_SET_PROPERTY_INFO(port_info, DMPS_DB_PSD_RX_POLARITY,   p_serdes_cfg->rx_polarity);
        DMPS_DB_SET_PROPERTY_INFO(port_info, DMPS_DB_PSD_TX_POLARITY,   p_serdes_cfg->tx_polarity);
        DMPS_DB_SET_PROPERTY_INFO(port_info, DMPS_DB_PSD_OCS,           CTC_CHIP_SERDES_OCS_MODE_NONE);
        DMPS_DB_SET_PROPERTY_INFO(port_info, DMPS_DB_PSD_LANE_ID,       physic_lane_id);
        DMPS_DB_SET_PROPERTY_INFO(port_info, DMPS_DB_PSD_SUPPORT_SPEED, support_speed);
        DMPS_DB_SET_PROPERTY_INFO(port_info, DMPS_DB_PSD_SPEED,         serdes_speed);
        
        /* serdes mode is none */
        if(0 == lane_num)
        {
            pcs_l  = SYS_DMPS_INVALID_U8;
            mac_id = logic_serdes;
            pcs_id = mac_id;

            /* MAC DB */
            DMPS_DB_SET_PROPERTY_INFO(port_info, DMPS_DB_MAC_EN,       FALSE);
            DMPS_DB_SET_PROPERTY_INFO(port_info, DMPS_DB_MAC_SPEED,    0);
            DMPS_DB_SET_PROPERTY_INFO(port_info, DMPS_DB_MAC_GROUP_ID, SYS_TMG_GET_MAC_GROUP(mac_id));
            DMPS_DB_SET_PROPERTY_INFO(port_info, DMPS_DB_MAC_IDX,      SYS_TMG_GET_QUAD_MAC_ID(mac_id));

            /* PCS DB */
            DMPS_DB_SET_PROPERTY_INFO(port_info, DMPS_DB_PCS_IDX,      SYS_TMG_GET_QUAD_MAC_ID(mac_id));

            if(is_occupy)
            {
                CTC_ERROR_RETURN(sys_usw_dmps_db_upt_info_init(lchip, &port_info_p));
                /* PORT DB */
                DMPS_DB_SET_MAP_INFO(port_info_p, DMPS_DB_DPORT,                   dport); 
                DMPS_DB_SET_PROPERTY_INFO(port_info_p, DMPS_DB_PORT_TYPE,          SYS_DMPS_RSV_PORT);
                DMPS_DB_SET_PROPERTY_INFO(port_info_p, DMPS_DB_PORT_IF_MODE,       CTC_CHIP_SERDES_NONE_MODE);
                DMPS_DB_SET_PROPERTY_INFO(port_info_p, DMPS_DB_PORT_IS_AN_FIRST,   0);
                DMPS_DB_SET_PROPERTY_INFO(port_info_p, DMPS_DB_PORT_LINK_FSM,      PMA_RX_NONREADY);
                DMPS_DB_SET_PROPERTY_INFO(port_info_p, DMPS_DB_PORT_LINK_MODE,     g_port_link_mode);

                CTC_ERROR_RETURN(sys_usw_dmps_db_set_port_info(lchip, &port_info_p));
            }

            dport   = SYS_DMPS_INVALID_U16;
            chan_id = SYS_DMPS_INVALID_U16;

            /*build map_node_list*/
            DMPS_DB_SET_MAP_UPDATE(port_info);
            DMPS_DB_SET_MAP_INFO(port_info, DMPS_DB_DPORT,         dport);
            DMPS_DB_SET_MAP_INFO(port_info, DMPS_DB_CHAN_ID,       chan_id);
            DMPS_DB_SET_MAP_INFO(port_info, DMPS_DB_CHAN_RX_ID,    chan_id);
            DMPS_DB_SET_MAP_INFO(port_info, DMPS_DB_MAC_ID,        mac_id);
            DMPS_DB_SET_MAP_INFO(port_info, DMPS_DB_PCS_ID,        pcs_id);
            DMPS_DB_SET_MAP_INFO(port_info, DMPS_DB_LOGIC_SERDES,  logic_serdes);
            DMPS_DB_SET_MAP_INFO(port_info, DMPS_DB_PHYSIC_SERDES, physic_serdes);
            
            CTC_ERROR_RETURN(sys_usw_dmps_db_set_port_info(lchip, &port_info));

            if (logic_serdes >= SYS_TMG_MAX_SERDES_NUM_NW)
            {
                p_map.lport   = dport;
                p_map.chan_id = chan_id;
                CTC_ERROR_RETURN(sys_usw_dmps_db_set_cpumac_map(lchip, logic_serdes - SYS_TMG_MAX_SERDES_NUM_NW, &p_map));
            }
        }
        /* serdes mode is valid */
        else
        {
            pcs_l        = logic_serdes % lane_num;

            /* port_nmu : serdes_num = 1 : N */
            mac_id  = logic_serdes / lane_num * lane_num;
            mac_group_id = SYS_TMG_GET_MAC_GROUP(mac_id);
            mac_idx      = SYS_TMG_GET_QUAD_MAC_ID(mac_id);
            pcs_id       = mac_id;
            pcs_idx      = mac_idx;
                                        
            if(0 == pcs_l)
            {
                /* MAC DB */
                DMPS_DB_SET_PROPERTY_INFO(port_info, DMPS_DB_MAC_EN,       FALSE);
                DMPS_DB_SET_PROPERTY_INFO(port_info, DMPS_DB_MAC_SPEED,    0);
                DMPS_DB_SET_PROPERTY_INFO(port_info, DMPS_DB_MAC_GROUP_ID, mac_group_id);
                DMPS_DB_SET_PROPERTY_INFO(port_info, DMPS_DB_MAC_IDX,      mac_idx);
        
                /* PCS DB */
                DMPS_DB_SET_PROPERTY_INFO(port_info, DMPS_DB_PCS_IDX,      pcs_idx);
        
                if(is_occupy)
                {
                    /* PORT DB */
                    SYS_TMG_GET_PORT_IFTYPE(if_mode, if_type);
                    DMPS_DB_SET_PROPERTY_INFO(port_info, DMPS_DB_PORT_TYPE,          port_type);
                    DMPS_DB_SET_PROPERTY_INFO(port_info, DMPS_DB_PORT_IF_MODE,       if_mode);
                    DMPS_DB_SET_PROPERTY_INFO(port_info, DMPS_DB_PORT_FEC_TYPE,      fec_type);
                    DMPS_DB_SET_PROPERTY_INFO(port_info, DMPS_DB_PORT_IF_TYPE,       if_type);
                    DMPS_DB_SET_PROPERTY_INFO(port_info, DMPS_DB_PORT_IS_AN_FIRST,   0);
                    DMPS_DB_SET_PROPERTY_INFO(port_info, DMPS_DB_PORT_LINK_FSM,      PMA_RX_NONREADY);
                    DMPS_DB_SET_PROPERTY_INFO(port_info, DMPS_DB_PORT_LINK_MODE,     g_port_link_mode);
                    /*SGMII default enable CL37 AN*/
                    /*if(CTC_CHIP_SERDES_SGMII_MODE == if_mode ||
                       CTC_CHIP_SERDES_2DOT5G_MODE == if_mode)
                    {
                        DMPS_DB_SET_PROPERTY_INFO(port_info, DMPS_DB_PORT_AN_EN, 1);    
                    }*/
                       
                    /* CHAN DB */
                    SYS_DMPS_GET_PORT_SPEED(if_mode, speed_mode);
                    DMPS_DB_SET_PROPERTY_INFO(port_info, DMPS_DB_CHAN_SPEED_MODE,    speed_mode);
                    DMPS_DB_SET_PROPERTY_INFO(port_info, DMPS_DB_CHAN_RX_SPEED_MODE, speed_mode);
                }
            }
            else
            {
                CTC_ERROR_RETURN(sys_usw_dmps_db_upt_info_init(lchip, &port_info_p));
                DMPS_DB_SET_MAP_INFO(port_info_p, DMPS_DB_MAC_ID, mac_id + pcs_l);
                DMPS_DB_SET_MAP_INFO(port_info_p, DMPS_DB_PCS_ID, pcs_id + pcs_l);
                DMPS_DB_SET_PROPERTY_INFO(port_info_p, DMPS_DB_MAC_GROUP_ID, mac_group_id);
                DMPS_DB_SET_PROPERTY_INFO(port_info_p, DMPS_DB_MAC_IDX,      mac_idx + pcs_l);
                DMPS_DB_SET_PROPERTY_INFO(port_info_p, DMPS_DB_PCS_IDX,      pcs_idx + pcs_l);
        
                if(is_occupy)
                {
                    /* PORT DB */
                    DMPS_DB_SET_MAP_INFO(port_info_p, DMPS_DB_DPORT,   dport); 
                    DMPS_DB_SET_PROPERTY_INFO(port_info_p, DMPS_DB_PORT_TYPE,          SYS_DMPS_RSV_PORT);
                    DMPS_DB_SET_PROPERTY_INFO(port_info_p, DMPS_DB_PORT_IS_AN_FIRST,   0);
                    DMPS_DB_SET_PROPERTY_INFO(port_info_p, DMPS_DB_PORT_LINK_FSM,      PMA_RX_NONREADY);
                    DMPS_DB_SET_PROPERTY_INFO(port_info_p, DMPS_DB_PORT_LINK_MODE,     g_port_link_mode);
                }
        
                CTC_ERROR_RETURN(sys_usw_dmps_db_set_port_info(lchip, &port_info_p)); 
        
                dport   = dport_prv;
                chan_id = chan_prv;
            }

            /*build map_node_list*/
            DMPS_DB_SET_MAP_UPDATE(port_info);
            DMPS_DB_SET_MAP_INFO(port_info, DMPS_DB_DPORT,         dport);
            DMPS_DB_SET_MAP_INFO(port_info, DMPS_DB_CHAN_ID,       chan_id);
            DMPS_DB_SET_MAP_INFO(port_info, DMPS_DB_CHAN_RX_ID,    chan_id);
            DMPS_DB_SET_MAP_INFO(port_info, DMPS_DB_MAC_ID,        mac_id);
            DMPS_DB_SET_MAP_INFO(port_info, DMPS_DB_PCS_ID,        pcs_id);
            DMPS_DB_SET_MAP_INFO(port_info, DMPS_DB_LOGIC_SERDES,  logic_serdes);
            DMPS_DB_SET_MAP_INFO(port_info, DMPS_DB_PHYSIC_SERDES, physic_serdes);
            
            CTC_ERROR_RETURN(sys_usw_dmps_db_set_port_info(lchip, &port_info));

            if (logic_serdes >= SYS_TMG_MAX_SERDES_NUM_NW)
            {
                (void) _sys_tmg_datapath_get_lport_chan_by_serdes(lchip, logic_serdes, &p_map.chan_id, &p_map.lport);
                CTC_ERROR_RETURN(sys_usw_dmps_db_set_cpumac_map(lchip, logic_serdes - SYS_TMG_MAX_SERDES_NUM_NW, &p_map));
            }
            
            /*ready for duplication check*/
            dport_prv  = dport;
            chan_prv   = chan_id;
        }
    }

    return CTC_E_NONE;
}

int32 
_sys_tmg_datapath_set_mac_group_valid(uint8 lchip, ctc_datapath_global_cfg_t* p_datapath_cfg)
{
    uint32 mgrp_v_bmp = 0;
    uint16 lsd;
    uint16 dp_hss;
    uint16 grp;
    uint16 grp_bit;
    uint8  dp;
    uint8  lane;
    uint8  valid = FALSE;

    for(dp = 0; dp < SYS_TMG_DP_NUM; dp++)
    {
        /*bit 0~9:   HSS 0~9 valid flag       */
        /*bit 11~20: HSS 10~19 valid flag     */
        for(dp_hss = 0; dp_hss < SYS_TMG_MAX_HSS_NUM_PER_DP; dp_hss++)
        {
            grp = dp*SYS_TMG_MAX_HSS_NUM_PER_DP + dp_hss;
            valid = FALSE;
            for(lane = 0; lane < SYS_TMG_LANE_NUM_PER_HSS; lane++)
            {
                lsd = grp*SYS_TMG_LANE_NUM_PER_HSS + lane;
                SYS_CONDITION_CONTINUE(lsd >= CTC_DATAPATH_SERDES_NUM);
                if(!SYS_TMG_IS_SERDES_ABANDON(p_datapath_cfg->serdes[lsd].mode, p_datapath_cfg->serdes[lsd].is_dynamic))
                {
                    valid = TRUE;
                    break;
                }
            }
            grp_bit = (1 == dp) ? (grp + 1) : grp;
            if(valid) mgrp_v_bmp |= (0x00000001 << grp_bit);
        }
        
        /*bit 10:    CPUMAC in DP 0 valid flag*/
        /*bit 21:    CPUMAC in DP 1 valid flag*/
        valid = ((!SYS_TMG_IS_SERDES_ABANDON(p_datapath_cfg->serdes[80+2*dp].mode, p_datapath_cfg->serdes[80+2*dp].is_dynamic)) || 
                 (!SYS_TMG_IS_SERDES_ABANDON(p_datapath_cfg->serdes[81+2*dp].mode, p_datapath_cfg->serdes[81+2*dp].is_dynamic))) ? 
                TRUE : FALSE;
        grp_bit = (1 == dp) ? 21 : 10;
        if(valid) mgrp_v_bmp |= (0x00000001 << grp_bit);
    }
    printf("MAC GROUP VALID: 0x%08x\n", mgrp_v_bmp);
    CTC_ERROR_RETURN(sys_usw_dmps_db_set_mac_group_valid(lchip, 0, mgrp_v_bmp));

    return CTC_E_NONE;
}

STATIC int32
_sys_tmg_datapath_init_db(uint8 lchip, ctc_datapath_global_cfg_t* p_datapath_cfg)
{
    uint8  bpe_full_mode = 0;
    uint16 index = 0;
    sys_internal_port_info_t port_info = {0};

    SYS_CONDITION_RETURN(!p_datapath_cfg, CTC_E_INVALID_PTR);

    CTC_ERROR_RETURN(sys_usw_dmps_db_set_core_pll(lchip, p_datapath_cfg->core_frequency_a));

    CTC_ERROR_RETURN(_sys_tmg_datapath_set_mac_group_valid(lchip, p_datapath_cfg));
    
    if (!CTC_WB_ENABLE(lchip) || CTC_WB_STATUS(lchip) != CTC_WB_STATUS_RELOADING)
    {
        CTC_ERROR_RETURN(_sys_tmg_datapath_init_chan_2_logic_serdes_map(lchip, p_datapath_cfg));
        CTC_ERROR_RETURN(_sys_tmg_datapath_init_mapping(lchip, p_datapath_cfg));
       /*update ext port start id*/
        for (index = SYS_INTERNAL_PORT_START; index <= SYS_INTERNAL_PORT_END; index++)
        {
            port_info.lport = index;
            port_info.chan_id = SYS_DMPS_INVALID_CHAN_ID;
            port_info.pp_id = SYS_DMPS_INVALID_U8;
            port_info.dp_id = SYS_DMPS_INVALID_U8;
            port_info.sub_chan_id = SYS_DMPS_INVALID_SUB_CHAN_ID;
            port_info.speed_mode = CTC_PORT_SPEED_MAX;
            port_info.port_type = SYS_DMPS_RSV_PORT;
            CTC_ERROR_RETURN(sys_usw_dmps_db_set_internal_port_info(lchip, &port_info));
            (void)sys_usw_dmps_db_assign_port(lchip, port_info.lport);
        }
    }
    bpe_full_mode = p_datapath_cfg->bpe_full_mode;
    CTC_ERROR_RETURN(sys_usw_dmps_db_set_bpe_full_mode(lchip, bpe_full_mode));
    if(bpe_full_mode)
    {
        for(index = 0; index <= SYS_INTERNAL_PORT_END; index++)
        {
            CTC_ERROR_RETURN(sys_usw_dmps_db_set_ext_lport_map(lchip, index, DMPS_INVALID_VALUE_U16));
        }
        SYS_INTERNAL_PORT_START = 0;
    }
    return CTC_E_NONE;
}

#if defined(EMULATION_ENV)
int32
_sys_tmg_datapath_init_emu_cfg0(uint8 lchip)
{
    uint32  cmd       = 0;
    uint32  index     = 0;
    uint32  txqm     = 0;
    uint32  txqm_mac = 0;
    uint32  value = 0;
    MacShimRxRdCalendar_m ms_cal;
    MacShimRegCfg_m ms_cfg;

    /*write chip 0 tbl-reg MacShimRxRdCalendar.0 0 field portId 0*/
    for(txqm = 0; txqm < 11; txqm++)
    {
        for(txqm_mac = 0; txqm_mac < 16; txqm_mac++)
        {
            index = DRV_INS(txqm, txqm_mac);
            cmd = DRV_IOR(MacShimRxRdCalendar_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &ms_cal));
            DRV_IOW_FIELD(lchip, MacShimRxRdCalendar_t, MacShimRxRdCalendar_portId_f, &txqm_mac, &ms_cal);
            cmd = DRV_IOW(MacShimRxRdCalendar_t, DRV_ENTRY_FLAG);
            CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &ms_cal));
        }
    }

    /*write chip 0 tbl-reg MacShimRegCfg.0 0 field base1gVlanId 32*/
    for(txqm = 0; txqm < 11; txqm++)
    {
        index = DRV_INS(txqm, 0);
        cmd = DRV_IOR(MacShimRegCfg_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &ms_cfg));
        value = 32+((txqm%5)*512);
        DRV_IOW_FIELD(lchip, MacShimRegCfg_t, MacShimRegCfg_base1gVlanId_f, &value, &ms_cfg);
        value = 0+((txqm%5)*512);
        DRV_IOW_FIELD(lchip, MacShimRegCfg_t, MacShimRegCfg_base10gVlanId_f, &value, &ms_cfg);
        value = 64+((txqm%5)*512);
        DRV_IOW_FIELD(lchip, MacShimRegCfg_t, MacShimRegCfg_base25gVlanId_f, &value, &ms_cfg);
        value = 128+((txqm%5)*512);
        DRV_IOW_FIELD(lchip, MacShimRegCfg_t, MacShimRegCfg_base40gVlanId_f, &value, &ms_cfg);
        value = 192+((txqm%5)*512);
        DRV_IOW_FIELD(lchip, MacShimRegCfg_t, MacShimRegCfg_base50gVlanId_f, &value, &ms_cfg);
        value = 256+((txqm%5)*512);
        DRV_IOW_FIELD(lchip, MacShimRegCfg_t, MacShimRegCfg_base100gVlanId_f, &value, &ms_cfg);
        cmd = DRV_IOW(MacShimRegCfg_t, DRV_ENTRY_FLAG);
        CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &ms_cfg));
    }
    return CTC_E_NONE;
}

#endif

int32 
sys_tmg_datapath_lane_swap_cfg(uint8 lchip, uint8 hss_id, uint8 enable)
{
    uint32 tbl_id   = 0;
    uint32 fld_id   = 0;
    uint32 index    = 0;
    uint32 cmd      = 0;
    uint32 value    = (enable) ? 1 : 0; 

    SharedPcsLgCfg_m        lg_cfg;
    GlobalCtlSharedFec_m    fec_cfg;
    Hss32GClkTreeCfg_m      clktree_cfg;

    tbl_id = SharedPcsLgCfg_t;
    fld_id = SharedPcsLgCfg_lgPcsLane0And3SwapEn_f;
    index  = DRV_INS(hss_id, 0);
    cmd    = DRV_IOR(tbl_id, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &lg_cfg));
    DRV_IOW_FIELD_NZ(lchip, tbl_id, fld_id, &value, &lg_cfg, hss_id, 0);
    cmd    = DRV_IOW(tbl_id, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &lg_cfg));

    tbl_id = GlobalCtlSharedFec_t;
    fld_id = GlobalCtlSharedFec_cfgSharedFecLane0And3SwapEn_f;
    cmd    = DRV_IOR(tbl_id, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &fec_cfg));
    DRV_IOW_FIELD_NZ(lchip, tbl_id, fld_id, &value, &fec_cfg, hss_id, 0);
    cmd    = DRV_IOW(tbl_id, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &fec_cfg));

    tbl_id = Hss32GClkTreeCfg_t;
    fld_id = Hss32GClkTreeCfg_cfgHssLane0And2SwapEn_f;
    cmd    = DRV_IOR(tbl_id, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &clktree_cfg));
    DRV_IOW_FIELD_NZ(lchip, tbl_id, fld_id, &value, &clktree_cfg, hss_id, 0);
    cmd    = DRV_IOW(tbl_id, DRV_ENTRY_FLAG);
    CTC_ERROR_RETURN(DRV_IOCTL(lchip, index, cmd, &clktree_cfg));

    return CTC_E_NONE;
}

int32
sys_tmg_datapath_init_lane_swap(uint8 lchip)
{
    uint8  index      = 0;
    uint16 lsd        = 0;
    uint16 lsd_lane   = 0;
    uint16 psd0       = 0;
    uint16 serdes_base = 0;
    uint8 cur_swap_flag = 0;

    for(index = 0; index < SYS_TMG_MAX_HSS_NUM + 1; index++)
    {
        /*. get current swap status*/
        serdes_base = SYS_TMG_LANE_NUM_PER_HSS * index;
        
        for(lsd_lane = 0; lsd_lane < SYS_TMG_LANE_NUM_PER_HSS; lsd_lane++)
        {
            SYS_CONDITION_CONTINUE(lsd_lane != 0 && lsd_lane != 2);
            lsd = serdes_base + lsd_lane;
            (void) sys_usw_dmps_db_get_relative_id(lchip, DMPS_DB_TYPE_LSD, lsd, DMPS_DB_TYPE_PSD, NULL, &psd0);
            if (DMPS_INVALID_VALUE_U16 != psd0)
            {
                cur_swap_flag = !(lsd == psd0);
                break;    
            }
        }

        CTC_ERROR_RETURN(sys_tmg_datapath_lane_swap_cfg(lchip, index, cur_swap_flag));
    }        

    return CTC_E_NONE;
}

int32
sys_tmg_datapath_init(uint8 lchip, ctc_datapath_global_cfg_t* p_datapath_cfg)
{
    if(g_dmps_dbg_sw)
    {
        if(NULL == g_tm_dump_fp)
        {
            g_tm_dump_fp = sal_fopen("./dump.txt", "w+");
        }
    }

#ifdef TMG_SERDES_SIM
    g_print_tbl = 1;    
#endif

    /*1. datapath_cfg.txt param check*/
    CTC_ERROR_RETURN(_sys_tmg_datapath_cfg_param_check(lchip, p_datapath_cfg));
    
#if (SDB_MEM_MODEL != SDB_MODE)
    /*2. core clock init */
    CTC_ERROR_RETURN(_sys_tmg_datapath_init_core_pll(lchip, p_datapath_cfg->core_frequency_a));
    
    /*3. sup init*/
    CTC_ERROR_RETURN(_sys_tmg_datapath_init_suprst(lchip));

    /*4. do packet buffer init*/
    //CTC_ERROR_RETURN(_sys_tmg_datapath_init_packet_buffer(lchip));
#endif

    /*5. data base init*/
    CTC_ERROR_RETURN(_sys_tmg_datapath_init_db(lchip, p_datapath_cfg));

#if (SDB_MEM_MODEL != SDB_MODE)
    /*6. module init*/
    CTC_ERROR_RETURN(_sys_tmg_datapath_init_module(lchip));

    /*7. do serdes init */
    CTC_ERROR_RETURN(_sys_tmg_datapath_init_serdes(lchip, p_datapath_cfg));

    /*8. dp/hss/txqm power down*/
    CTC_ERROR_RETURN(_sys_tmg_datapath_init_macpcs_power_down(lchip, p_datapath_cfg));

    /*9. omitted table init*/
    CTC_ERROR_RETURN(_sys_tmg_datapath_init_omitted_table(lchip));
#endif
    
#ifdef EMULATION_ENV
    ///TODO: EMU board type init cfg
#endif

#if (SDB_MEM_MODEL != SDB_MODE)
    /*10. datapath init */
    CTC_ERROR_RETURN(_sys_tmg_datapath_init_dp(lchip, p_datapath_cfg));

    /*11. pulse init*/
    CTC_ERROR_RETURN(_sys_tmg_datapath_init_pulse_cfg(lchip));
#endif
    /* 12. lane swap */
    CTC_ERROR_RETURN(sys_tmg_datapath_init_lane_swap(lchip));

#if (0 == SDK_WORK_PLATFORM)
    CTC_ERROR_RETURN(sys_tmg_serdes_init(lchip));
#endif

#if defined(EMULATION_ENV) && !defined(EMULATOR_ENV)
    CTC_ERROR_RETURN(_sys_tmg_datapath_init_emu_cfg0(lchip));
#endif

#ifdef TMG_SERDES_SIM
        g_print_tbl = 0;
#endif

#if (SDB_MEM_MODEL != SDB_MODE)
    /* 13. mcu init */
    CTC_ERROR_RETURN(sys_tmg_mcu_init(lchip));
#endif

    return CTC_E_NONE;
}

int32
_sys_tmg_datapath_get_free_chan(uint8 lchip, uint16 dport, uint8 free_num, uint16* free_chan, uint8* free_sub_chan, uint8* free_mac_client, uint8 dir)
{
    uint8  cnt        = 0;
    uint8  free_id    = 0;
    uint8  dp_id      = 0;
    uint8  txqm_id    = 0;
    uint8  txqm_id_per_dp = 0;
    uint8  is_rsv     = 0;
    uint16 p_sub_chan = SYS_TMG_USELESS_ID16;
    uint16 p_mac_cli  = SYS_TMG_USELESS_ID16;
    uint16 p_chan     = SYS_TMG_USELESS_ID16;
    uint16 start_chan = 0;
    uint16 end_chan   = 0;
    uint16 chan_temp  = 0;
    uint8  chan_used[SYS_TMG_NW_CHAN_NUM_PER_DP]            = {0};
    uint8  mac_client_used[SYS_TMG_MAC_CLIENT_NUM_PER_TXQM] = {0};
    sys_dmps_db_upt_info_t port_info  = {0};

    CTC_ERROR_RETURN(sys_usw_dmps_db_upt_info_init(lchip, &port_info));
    DMPS_DB_SET_MAP_INFO(port_info, DMPS_DB_DPORT, dport);
    DMPS_DB_SET_PROPERTY_UPDATE(port_info, GET_DP_ID_BY_DIR(dir));
    DMPS_DB_SET_PROPERTY_UPDATE(port_info, GET_TXQM_ID_BY_DIR(dir));
    CTC_ERROR_RETURN(sys_usw_dmps_db_get_port_info(lchip, &port_info));
    DMPS_DB_GET_PROPERTY_INFO(port_info, GET_DP_ID_BY_DIR(dir),   dp_id);
    DMPS_DB_GET_PROPERTY_INFO(port_info, GET_TXQM_ID_BY_DIR(dir), txqm_id);

    start_chan      = dp_id * SYS_TMG_CHANNEL_NUM_PER_DP;
    end_chan        = start_chan + SYS_TMG_NW_CHAN_NUM_PER_DP;
    txqm_id_per_dp  = txqm_id % SYS_TMG_TXQM_NUM_PER_DP; 

    /* traverse all channels in the same dp */
    for (chan_temp = start_chan; chan_temp < end_chan; chan_temp++)
    {
        CTC_ERROR_RETURN(sys_usw_dmps_db_upt_info_init(lchip, &port_info));
        DMPS_DB_SET_MAP_INFO(port_info, GET_CHAN_ID_BY_DIR(dir), chan_temp);
        DMPS_DB_SET_PROPERTY_UPDATE(port_info, GET_IS_RSV_BY_DIR(dir));
        CTC_ERROR_RETURN(sys_usw_dmps_db_get_port_info(lchip, &port_info));
        DMPS_DB_GET_PROPERTY_INFO(port_info, GET_IS_RSV_BY_DIR(dir), is_rsv);

        SYS_CONDITION_CONTINUE((!sys_usw_dmps_db_is_valid_id(lchip, GET_CHAN_TYPE_BY_DIR(dir), chan_temp)) && (!is_rsv));

        CTC_ERROR_RETURN(sys_usw_dmps_db_upt_info_init(lchip, &port_info));
        DMPS_DB_SET_MAP_INFO(port_info, GET_CHAN_ID_BY_DIR(dir), chan_temp);
        DMPS_DB_SET_PROPERTY_UPDATE(port_info, GET_SUB_CHAN_ID_BY_DIR(dir));
        DMPS_DB_SET_PROPERTY_UPDATE(port_info, GET_MAC_CLIENT_ID_BY_DIR(dir));
        CTC_ERROR_RETURN(sys_usw_dmps_db_get_port_info(lchip, &port_info));
        DMPS_DB_GET_PROPERTY_INFO(port_info, GET_SUB_CHAN_ID_BY_DIR(dir),   p_sub_chan);
        DMPS_DB_GET_PROPERTY_INFO(port_info, GET_MAC_CLIENT_ID_BY_DIR(dir), p_mac_cli);
        
        chan_used[p_sub_chan] = TRUE;   
        mac_client_used[p_mac_cli % SYS_TMG_MAC_CLIENT_NUM_PER_TXQM] = TRUE;
    
    }

    for (free_id = 0; free_id < free_num; free_id++)
    {
        p_sub_chan = SYS_TMG_USELESS_ID16;
        p_mac_cli  = SYS_TMG_USELESS_ID16;
        p_chan     = SYS_TMG_USELESS_ID16;
        /* select free chan in the same dp */
        for (cnt = 0; cnt < SYS_TMG_NW_CHAN_NUM_PER_DP; cnt++)
        {
            if (!chan_used[cnt])
            {
                p_sub_chan = cnt;
                chan_used[cnt] = TRUE;
                break;
            }
        }

        /* select free mac_client in the same txqm */
        for (cnt = 0; cnt < SYS_TMG_MAC_CLIENT_NUM_PER_TXQM; cnt++)
        {
            if (!mac_client_used[cnt])
            {
                p_mac_cli = cnt + txqm_id_per_dp * SYS_TMG_MAC_CLIENT_NUM_PER_TXQM;
                mac_client_used[cnt] = TRUE;
                break;
            }
        }

        if ((SYS_TMG_USELESS_ID16 == p_sub_chan) || (SYS_TMG_USELESS_ID16 == p_mac_cli))
        {
            SYS_DATAPATH_DBG_OUT(CTC_DEBUG_LEVEL_ERROR, "%% There is no free channel! \n");
            return CTC_E_NO_RESOURCE;
        }

        /* config free chan */
        p_chan = start_chan + p_sub_chan;
        SYS_USW_VALID_PTR_WRITE(free_chan + free_id, p_chan);
        SYS_USW_VALID_PTR_WRITE(free_sub_chan + free_id, p_sub_chan);
        SYS_USW_VALID_PTR_WRITE(free_mac_client + free_id, p_mac_cli);
    }

    return CTC_E_NONE;
}

int32
sys_tmg_datapath_show_xpipe(uint8 lchip)
{
    uint16 idx      = 0; 
    uint16 lport    = 0;
    uint16 gport    = 0;
    uint16 dport    = 0;
    uint8  gchip_id = 0;
    uint32 mac_id[SYS_USW_MAX_CHANEL_NUM_PER_PORT]   = {0};
    uint32 chan_id[SYS_USW_MAX_CHANEL_NUM_PER_PORT]  = {0};
    uint16 dp_id    = 0;
    uint16 txqm_id  = 0;
    uint16 emac_id  = 0;
    uint16 pmac_id  = 0;
    uint16 echan_id = 0;
    uint16 pchan_id = 0;
    uint16 xpipe_en = 0;
    uint16 port_type = 0;
    
    sys_dmps_db_upt_info_t port_info = {0};
    sys_dmps_port_info_t   upt_info  = {0};

    SYS_DATAPATH_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "-------------------------------------------------------------------\n");
    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "TX-DIR  %-8s%-5s%-7s%-10s%-8s%-9s%-8s%-9s\n",
                      "GPort", "DP", "TXQM", "XPIPE-EN", "E-MAC", "E-CHAN", "P-MAC", "P-CHAN");
    SYS_DATAPATH_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "-------------------------------------------------------------------\n");

    CTC_ERROR_RETURN(sys_usw_get_gchip_id(lchip, &gchip_id));

    for(lport = 0; lport < SYS_USW_MAX_PORT_NUM_PER_CHIP; lport++)
    {
        SYS_CONDITION_CONTINUE(FALSE == sys_usw_dmps_db_is_lport_valid(lchip, lport));

        gport = SYS_MAP_DRV_LPORT_TO_CTC_GPORT(gchip_id, lport);
        dport = sys_usw_dmps_db_get_dport_by_lport(lchip, lport);
        
        CTC_ERROR_RETURN(sys_usw_dmps_db_upt_info_init(lchip, &port_info));
        DMPS_DB_SET_MAP_INFO(port_info, DMPS_DB_DPORT, dport);
        DMPS_DB_SET_PROPERTY_UPDATE(port_info, DMPS_DB_CHAN_DP_ID);
        DMPS_DB_SET_PROPERTY_UPDATE(port_info, DMPS_DB_CHAN_TXQM_ID);
        DMPS_DB_SET_PROPERTY_UPDATE(port_info, DMPS_DB_PORT_XPIPE_EN);
        DMPS_DB_SET_PROPERTY_UPDATE(port_info, DMPS_DB_PORT_TYPE);
        CTC_ERROR_RETURN(sys_usw_dmps_db_get_port_info(lchip, &port_info));
        DMPS_DB_GET_PROPERTY_INFO(port_info, DMPS_DB_CHAN_DP_ID,   dp_id);       
        DMPS_DB_GET_PROPERTY_INFO(port_info, DMPS_DB_CHAN_TXQM_ID,   txqm_id);
        DMPS_DB_GET_PROPERTY_INFO(port_info, DMPS_DB_PORT_XPIPE_EN, xpipe_en);
        DMPS_DB_GET_PROPERTY_INFO(port_info, DMPS_DB_PORT_TYPE, port_type);

        SYS_CONDITION_CONTINUE(!CHAN_DIR_IS_TX(xpipe_en) || port_type != SYS_DMPS_NETWORK_PORT);
        
        for(idx = 0; idx < SYS_USW_MAX_CHANEL_NUM_PER_PORT; idx++)
        {
            upt_info.lport = lport;
            upt_info.dir_bmp   = CHAN_DIR_TX;
            upt_info.index = idx;
            CTC_ERROR_RETURN(sys_usw_dmps_db_api_get_port_property(lchip, &upt_info, SYS_PORT_API_DMPS_PROP_GET_PMAC_ID, &mac_id[idx]));
            CTC_ERROR_RETURN(sys_usw_dmps_db_api_get_port_property(lchip, &upt_info, SYS_PORT_API_DMPS_PROP_CHAN_ID, &chan_id[idx]));
        }

        pmac_id     = mac_id[1];
        emac_id     = mac_id[0];
        pchan_id    = chan_id[1];
        echan_id    = chan_id[0];

        SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "       0x%04x  %-5u%-7u%-10u%-8u%-9u%-8u%-9u\n",
                        gport, dp_id, txqm_id, xpipe_en,
                        emac_id, echan_id, pmac_id, pchan_id);
    }


    SYS_DATAPATH_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "-------------------------------------------------------------------\n");
    SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "RX-DIR  %-8s%-5s%-7s%-10s%-8s%-9s%-8s%-9s\n",
                      "GPort", "DP", "TXQM", "XPIPE-EN", "E-MAC", "E-CHAN", "P-MAC", "P-CHAN");
    SYS_DATAPATH_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "-------------------------------------------------------------------\n");

    for(lport = 0; lport < SYS_USW_MAX_PORT_NUM_PER_CHIP; lport++)
    {
        SYS_CONDITION_CONTINUE(FALSE == sys_usw_dmps_db_is_lport_valid(lchip, lport));

        gport = SYS_MAP_DRV_LPORT_TO_CTC_GPORT(gchip_id, lport);
        dport = sys_usw_dmps_db_get_dport_by_lport(lchip, lport);
        
        CTC_ERROR_RETURN(sys_usw_dmps_db_upt_info_init(lchip, &port_info));
        DMPS_DB_SET_MAP_INFO(port_info, DMPS_DB_DPORT, dport);
        DMPS_DB_SET_PROPERTY_UPDATE(port_info, DMPS_DB_CHAN_RX_DP_ID);
        DMPS_DB_SET_PROPERTY_UPDATE(port_info, DMPS_DB_CHAN_RX_TXQM_ID);
        DMPS_DB_SET_PROPERTY_UPDATE(port_info, DMPS_DB_PORT_XPIPE_EN);
        DMPS_DB_SET_PROPERTY_UPDATE(port_info, DMPS_DB_PORT_TYPE);
        CTC_ERROR_RETURN(sys_usw_dmps_db_get_port_info(lchip, &port_info));
        DMPS_DB_GET_PROPERTY_INFO(port_info, DMPS_DB_CHAN_RX_DP_ID,   dp_id);       
        DMPS_DB_GET_PROPERTY_INFO(port_info, DMPS_DB_CHAN_RX_TXQM_ID,   txqm_id);
        DMPS_DB_GET_PROPERTY_INFO(port_info, DMPS_DB_PORT_XPIPE_EN, xpipe_en);
        DMPS_DB_GET_PROPERTY_INFO(port_info, DMPS_DB_PORT_TYPE, port_type);

        SYS_CONDITION_CONTINUE(!CHAN_DIR_IS_RX(xpipe_en) || port_type != SYS_DMPS_NETWORK_PORT);

        for(idx = 0; idx < 2; idx++)
        {
            upt_info.lport = lport;
            upt_info.dir_bmp   = CHAN_DIR_RX;
            upt_info.index = idx;
            CTC_ERROR_RETURN(sys_usw_dmps_db_api_get_port_property(lchip, &upt_info, SYS_PORT_API_DMPS_PROP_GET_PMAC_ID, &mac_id[idx]));
            CTC_ERROR_RETURN(sys_usw_dmps_db_api_get_port_property(lchip, &upt_info, SYS_PORT_API_DMPS_PROP_CHAN_ID, &chan_id[idx]));
        }
        
        pmac_id     = mac_id[1];
        emac_id     = mac_id[0];
        pchan_id    = chan_id[1];
        echan_id    = chan_id[0];

        SYS_MAC_DBG_OUT(CTC_DEBUG_LEVEL_DUMP, "       0x%04x  %-5u%-7u%-10u%-8u%-9u%-8u%-9u\n",
                        gport, dp_id, txqm_id, xpipe_en,
                        emac_id, echan_id, pmac_id, pchan_id);
    }

    return CTC_E_NONE;    
}

int32
_sys_tmg_datapath_xpipe_resource_alloc(uint8 lchip, uint16 dport, uint8 chan_num, uint16* chan_list, uint8 dir)
{
    uint8  cnt      = 0;
    uint8  dp_id    = 0;
    uint8  txqm_id  = 0;
    uint16 chan_id  = 0;
    uint16 dp_chan  = 0;
    sys_dmps_db_upt_info_t port_info  = {0};
    sys_dmps_db_chan_info_t chan_info = {0};

    if (NULL == chan_list)
    {
        return CTC_E_INVALID_PARAM;
    }

    CTC_ERROR_RETURN(sys_usw_dmps_db_upt_info_init(lchip, &port_info));
    DMPS_DB_SET_MAP_INFO(port_info, DMPS_DB_DPORT, dport);
    DMPS_DB_SET_PROPERTY_UPDATE(port_info, DMPS_DB_CHAN_CORE_ID);
    DMPS_DB_SET_PROPERTY_UPDATE(port_info, DMPS_DB_CHAN_PP_ID);
    DMPS_DB_SET_PROPERTY_UPDATE(port_info, DMPS_DB_CHAN_DP_ID);
    DMPS_DB_SET_PROPERTY_UPDATE(port_info, DMPS_DB_CHAN_TXQM_ID);
    CTC_ERROR_RETURN(sys_usw_dmps_db_get_port_info(lchip, &port_info));
    DMPS_DB_GET_PROPERTY_INFO(port_info, DMPS_DB_CHAN_DP_ID,       dp_id);
    DMPS_DB_GET_PROPERTY_INFO(port_info, DMPS_DB_CHAN_TXQM_ID,     txqm_id);

    /* 1. resource alloc by group */
    CTC_ERROR_RETURN(_sys_tmg_datapath_resource_alloc_group(lchip, dp_id, txqm_id, TRUE, dir));

    for (cnt = 0; cnt < chan_num; cnt++)
    {
        chan_id = chan_list[cnt];
        chan_info.chan_id = chan_id;
        CTC_ERROR_RETURN(sys_usw_dmps_db_get_chan_info(lchip, &chan_info, dir));

        /* 2. resource alloc by chan */
        CTC_ERROR_RETURN(_sys_tmg_datapath_resource_alloc_chan(lchip, chan_id, TRUE, dir, TRUE));

        /*3. cfg mapping */
        dp_chan = SYS_TMG_CHANNEL_TO_DPCHAN(chan_id);
        CTC_ERROR_RETURN(_sys_tmg_datapath_set_map_by_chan(lchip, dp_id, dp_chan, dir));       
    }

    return CTC_E_NONE;
}


